25 changed files with 2325 additions and 39 deletions
@ -1,6 +0,0 @@ |
|||||
require('bignum').config({ |
|
||||
EXPONENTIAL_AT: 9999999, |
|
||||
DECIMAL_PLACES: 0, |
|
||||
ROUNDING_MODE: 1, |
|
||||
}); |
|
||||
|
|
@ -0,0 +1,116 @@ |
|||||
|
var crypto = require('crypto'); |
||||
|
var bignum = require('./Bignum'); |
||||
|
|
||||
|
var globalBuffer = new Buffer(1024); |
||||
|
var zerobuf = new Buffer(0); |
||||
|
var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; |
||||
|
var ALPHABET_ZERO = ALPHABET[0]; |
||||
|
var ALPHABET_BUF = new Buffer(ALPHABET, 'ascii'); |
||||
|
var ALPHABET_INV = {}; |
||||
|
for(var i=0; i < ALPHABET.length; i++) { |
||||
|
ALPHABET_INV[ALPHABET[i]] = i; |
||||
|
}; |
||||
|
|
||||
|
// Vanilla Base58 Encoding
|
||||
|
var base58 = { |
||||
|
encode: function(buf) { |
||||
|
var str; |
||||
|
var x = bignum.fromBuffer(buf); |
||||
|
var r; |
||||
|
|
||||
|
if(buf.length < 512) { |
||||
|
str = globalBuffer; |
||||
|
} else { |
||||
|
str = new Buffer(buf.length << 1); |
||||
|
} |
||||
|
var i = str.length - 1; |
||||
|
while(x.gt(0)) { |
||||
|
r = x.mod(58); |
||||
|
x = x.div(58); |
||||
|
str[i] = ALPHABET_BUF[r.toNumber()]; |
||||
|
i--; |
||||
|
} |
||||
|
|
||||
|
// deal with leading zeros
|
||||
|
var j=0; |
||||
|
while(buf[j] == 0) { |
||||
|
str[i] = ALPHABET_BUF[0]; |
||||
|
j++; i--; |
||||
|
} |
||||
|
|
||||
|
return str.slice(i+1,str.length).toString('ascii'); |
||||
|
}, |
||||
|
|
||||
|
decode: function(str) { |
||||
|
if(str.length == 0) return zerobuf; |
||||
|
var answer = bignum(0); |
||||
|
for(var i=0; i<str.length; i++) { |
||||
|
answer.mul(58) |
||||
|
answer = answer.mul(58); |
||||
|
answer = answer.add(ALPHABET_INV[str[i]]); |
||||
|
}; |
||||
|
var i = 0; |
||||
|
while(i < str.length && str[i] == ALPHABET_ZERO) { |
||||
|
i++; |
||||
|
} |
||||
|
if(i > 0) { |
||||
|
var zb = new Buffer(i); |
||||
|
zb.fill(0); |
||||
|
if(i == str.length) return zb; |
||||
|
answer = answer.toBuffer(); |
||||
|
return Buffer.concat([zb, answer], i+answer.length); |
||||
|
} else { |
||||
|
return answer.toBuffer(); |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
// Base58Check Encoding
|
||||
|
function sha256(data) { |
||||
|
return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary'); |
||||
|
}; |
||||
|
|
||||
|
function doubleSHA256(data) { |
||||
|
return sha256(sha256(data)); |
||||
|
}; |
||||
|
|
||||
|
var base58Check = { |
||||
|
encode: function(buf) { |
||||
|
var checkedBuf = new Buffer(buf.length + 4); |
||||
|
var hash = doubleSHA256(buf); |
||||
|
buf.copy(checkedBuf); |
||||
|
hash.copy(checkedBuf, buf.length); |
||||
|
return base58.encode(checkedBuf); |
||||
|
}, |
||||
|
|
||||
|
decode: function(s) { |
||||
|
var buf = base58.decode(s); |
||||
|
if (buf.length < 4) { |
||||
|
throw new Error("invalid input: too short"); |
||||
|
} |
||||
|
|
||||
|
var data = buf.slice(0, -4); |
||||
|
var csum = buf.slice(-4); |
||||
|
|
||||
|
var hash = doubleSHA256(data); |
||||
|
var hash4 = hash.slice(0, 4); |
||||
|
|
||||
|
if (csum.toString() != hash4.toString()) { |
||||
|
throw new Error("checksum mismatch"); |
||||
|
} |
||||
|
|
||||
|
return data; |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
// if you frequently do base58 encodings with data larger
|
||||
|
// than 512 bytes, you can use this method to expand the
|
||||
|
// size of the reusable buffer
|
||||
|
exports.setBuffer = function(buf) { |
||||
|
globalBuffer = buf; |
||||
|
}; |
||||
|
|
||||
|
exports.base58 = base58; |
||||
|
exports.base58Check = base58Check; |
||||
|
exports.encode = base58.encode; |
||||
|
exports.decode = base58.decode; |
@ -0,0 +1,5 @@ |
|||||
|
if (process.versions) { |
||||
|
module.exports = require('bignum'); |
||||
|
return; |
||||
|
} |
||||
|
module.exports = require('./browser/Bignum'); |
File diff suppressed because it is too large
@ -0,0 +1,49 @@ |
|||||
|
var assert = require('assert'); |
||||
|
var base58 = require('../lib/Base58').base58; |
||||
|
var base58Check = require('../lib/Base58').base58Check; |
||||
|
|
||||
|
var testData = [ |
||||
|
["61", "2g", "C2dGTwc"], |
||||
|
["626262", "a3gV", "4jF5uERJAK"], |
||||
|
["636363", "aPEr", "4mT4krqUYJ"], |
||||
|
["73696d706c792061206c6f6e6720737472696e67", "2cFupjhnEsSn59qHXstmK2ffpLv2", "BXF1HuEUCqeVzZdrKeJjG74rjeXxqJ7dW"], |
||||
|
["00eb15231dfceb60925886b67d065299925915aeb172c06647", "1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L", "13REmUhe2ckUKy1FvM7AMCdtyYq831yxM3QeyEu4"], |
||||
|
["516b6fcd0f", "ABnLTmg", "237LSrY9NUUas"], |
||||
|
["bf4f89001e670274dd", "3SEo3LWLoPntC", "GwDDDeduj1jpykc27e"], |
||||
|
["572e4794", "3EFU7m", "FamExfqCeza"], |
||||
|
["ecac89cad93923c02321", "EJDM8drfXA6uyA", "2W1Yd5Zu6WGyKVtHGMrH"], |
||||
|
["10c8511e", "Rt5zm", "3op3iuGMmhs"], |
||||
|
["00000000000000000000", "1111111111", "111111111146Momb"], |
||||
|
["", "", "3QJmnh"] |
||||
|
]; |
||||
|
|
||||
|
//suite('basic');
|
||||
|
|
||||
|
test('allData', function() { |
||||
|
base58.encodeTest = function(raw, b58str) { |
||||
|
assert.equal(base58.encode(raw), b58str); |
||||
|
}; |
||||
|
|
||||
|
base58.decodeTest = function(raw, b58str) { |
||||
|
assert.equal(raw.toString('hex'), base58.decode(b58str).toString('hex')); |
||||
|
}; |
||||
|
|
||||
|
base58Check.encodeTest = function(raw, b58str) { |
||||
|
assert.equal(base58Check.encode(raw), b58str); |
||||
|
}; |
||||
|
|
||||
|
base58Check.decodeTest = function(raw, b58str) { |
||||
|
assert.equal(raw.toString('hex'), base58Check.decode(b58str).toString('hex')); |
||||
|
}; |
||||
|
|
||||
|
testData.forEach(function(datum) { |
||||
|
var raw = new Buffer(datum[0], 'hex'); |
||||
|
var b58 = datum[1]; |
||||
|
var b58Check = datum[2]; |
||||
|
|
||||
|
base58.encodeTest(raw, b58); |
||||
|
base58.decodeTest(raw, b58); |
||||
|
base58Check.encodeTest(raw, b58Check); |
||||
|
base58Check.decodeTest(raw, b58Check); |
||||
|
}); |
||||
|
}); |
Loading…
Reference in new issue