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