Daniel Cousens
9 years ago
4 changed files with 320 additions and 0 deletions
@ -0,0 +1,66 @@ |
|||||
|
function decode (buffer, maxLength, minimal) { |
||||
|
maxLength = maxLength || 4 |
||||
|
minimal = minimal === undefined ? true : minimal |
||||
|
|
||||
|
var length = buffer.length |
||||
|
if (length === 0) return 0 |
||||
|
if (length > maxLength) throw new TypeError('Script number overflow') |
||||
|
if (minimal) { |
||||
|
if ((buffer[length - 1] & 0x7f) === 0) { |
||||
|
if (length <= 1 || (buffer[length - 2] & 0x80) === 0) throw new Error('Non-minimally encoded script number') |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 40-bit
|
||||
|
if (length === 5) { |
||||
|
var a = buffer.readUInt32LE(0) |
||||
|
var b = buffer.readUInt8(4) |
||||
|
|
||||
|
if (b & 0x80) return -((b & ~0x80) * 0x100000000 + a) |
||||
|
return b * 0x100000000 + a |
||||
|
} |
||||
|
|
||||
|
var result = 0 |
||||
|
|
||||
|
// 32-bit / 24-bit / 16-bit / 8-bit
|
||||
|
for (var i = 0; i < length; ++i) { |
||||
|
result |= buffer[i] << (8 * i) |
||||
|
} |
||||
|
|
||||
|
if (buffer[length - 1] & 0x80) return -(result & ~(0x80 << (8 * (length - 1)))) |
||||
|
return result |
||||
|
} |
||||
|
|
||||
|
function scriptNumSize (i) { |
||||
|
return i > 0x7fffffff ? 5 |
||||
|
: i > 0x7fffff ? 4 |
||||
|
: i > 0x7fff ? 3 |
||||
|
: i > 0x7f ? 2 |
||||
|
: i > 0x00 ? 1 |
||||
|
: 0 |
||||
|
} |
||||
|
|
||||
|
function encode (number) { |
||||
|
var value = Math.abs(number) |
||||
|
var size = scriptNumSize(value) |
||||
|
var buffer = new Buffer(size) |
||||
|
var negative = number < 0 |
||||
|
|
||||
|
for (var i = 0; i < size; ++i) { |
||||
|
buffer.writeUInt8(value & 0xff, i) |
||||
|
value >>= 8 |
||||
|
} |
||||
|
|
||||
|
if (buffer[size - 1] & 0x80) { |
||||
|
buffer.writeUInt8(negative ? 0x80 : 0x00, size - 1) |
||||
|
} else if (negative) { |
||||
|
buffer[size - 1] |= 0x80 |
||||
|
} |
||||
|
|
||||
|
return buffer |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
decode: decode, |
||||
|
encode: encode |
||||
|
} |
@ -0,0 +1,225 @@ |
|||||
|
[ |
||||
|
{ |
||||
|
"hex": "", |
||||
|
"number": 0 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "01", |
||||
|
"number": 1 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "02", |
||||
|
"number": 2 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "03", |
||||
|
"number": 3 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "7e", |
||||
|
"number": 126 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "7f", |
||||
|
"number": 127 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "8000", |
||||
|
"number": 128 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "8100", |
||||
|
"number": 129 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "8200", |
||||
|
"number": 130 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ff00", |
||||
|
"number": 255 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fe7f", |
||||
|
"number": 32766 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ff7f", |
||||
|
"number": 32767 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "008000", |
||||
|
"number": 32768 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffff00", |
||||
|
"number": 65535 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "018000", |
||||
|
"number": 32769 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "028000", |
||||
|
"number": 32770 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffffff00", |
||||
|
"number": 16777215 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "feff7f", |
||||
|
"number": 8388606 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffff7f", |
||||
|
"number": 8388607 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "00008000", |
||||
|
"number": 8388608 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "01008000", |
||||
|
"number": 8388609 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "02008000", |
||||
|
"number": 8388610 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "feffff7f", |
||||
|
"number": 2147483646 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffffff7f", |
||||
|
"number": 2147483647 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0000008000", |
||||
|
"number": 2147483648 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0100008000", |
||||
|
"number": 2147483649 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0200008000", |
||||
|
"number": 2147483650 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "ffffffff00", |
||||
|
"number": 4294967295 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0200008080", |
||||
|
"number": -2147483650 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0100008080", |
||||
|
"number": -2147483649 |
||||
|
}, |
||||
|
{ |
||||
|
"bytes": 5, |
||||
|
"hex": "0000008080", |
||||
|
"number": -2147483648 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffffffff", |
||||
|
"number": -2147483647 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "feffffff", |
||||
|
"number": -2147483646 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fdffffff", |
||||
|
"number": -2147483645 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffffff80", |
||||
|
"number": -16777215 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "01008080", |
||||
|
"number": -8388609 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "00008080", |
||||
|
"number": -8388608 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffffff", |
||||
|
"number": -8388607 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "feffff", |
||||
|
"number": -8388606 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fdffff", |
||||
|
"number": -8388605 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffff80", |
||||
|
"number": -65535 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "018080", |
||||
|
"number": -32769 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "008080", |
||||
|
"number": -32768 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ffff", |
||||
|
"number": -32767 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "feff", |
||||
|
"number": -32766 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fdff", |
||||
|
"number": -32765 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ff80", |
||||
|
"number": -255 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "8180", |
||||
|
"number": -129 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "8080", |
||||
|
"number": -128 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "ff", |
||||
|
"number": -127 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fe", |
||||
|
"number": -126 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "fd", |
||||
|
"number": -125 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "82", |
||||
|
"number": -2 |
||||
|
}, |
||||
|
{ |
||||
|
"hex": "81", |
||||
|
"number": -1 |
||||
|
} |
||||
|
] |
@ -0,0 +1,27 @@ |
|||||
|
/* global describe, it */ |
||||
|
|
||||
|
var assert = require('assert') |
||||
|
var scriptNumber = require('../src/script_number') |
||||
|
var fixtures = require('./fixtures/script_number.json') |
||||
|
|
||||
|
describe('script', function () { |
||||
|
describe('decode', function () { |
||||
|
fixtures.forEach(function (f) { |
||||
|
it(f.hex + ' returns ' + f.number, function () { |
||||
|
var actual = scriptNumber.decode(new Buffer(f.hex, 'hex'), f.bytes) |
||||
|
|
||||
|
assert.strictEqual(actual, f.number) |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
|
|
||||
|
describe('encode', function () { |
||||
|
fixtures.forEach(function (f) { |
||||
|
it(f.number + ' returns ' + f.hex, function () { |
||||
|
var actual = scriptNumber.encode(f.number) |
||||
|
|
||||
|
assert.strictEqual(actual.toString('hex'), f.hex) |
||||
|
}) |
||||
|
}) |
||||
|
}) |
||||
|
}) |
Loading…
Reference in new issue