Skip to content

Commit

Permalink
bs58: use Buffers for internal calculation
Browse files Browse the repository at this point in the history
Ported from bitcoinjs-lib, uses BigInteger precomputation as well.
  • Loading branch information
dcousens committed Jun 26, 2014
1 parent 950cda4 commit 129c71d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 49 deletions.
94 changes: 46 additions & 48 deletions lib/bs58.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,73 @@
var BigInteger = require('bigi');

'use strict'

module.exports.decode = decode;
module.exports.encode = encode;

var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
var ALPHABET_BUF = new Buffer(ALPHABET)
var LOOKUP = {};
for (var i=0 ; i < ALPHABET.length ; ++i) {
LOOKUP[ALPHABET[i]] = i;
// Base58 encoding/decoding
// Originally written by Mike Hearn for BitcoinJ
// Copyright (c) 2011 Google Inc
// Ported to JavaScript by Stefan Thomas
// Merged Buffer refactorings from base58-native by Stephen Pair
// Copyright (c) 2013 BitPay Inc

var assert = require('assert')
var BigInteger = require('bigi')

var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
var ALPHABET_BUF = new Buffer(ALPHABET, 'ascii')
var ALPHABET_MAP = {}
for(var i = 0; i < ALPHABET.length; i++) {
ALPHABET_MAP[ALPHABET.charAt(i)] = BigInteger.valueOf(i)
}
var BASE = new BigInteger('58')

var BASE = 58;
var base = BigInteger.valueOf(BASE);


function encode (input) {
var bi = BigInteger.fromBuffer(input)
var result = new Buffer(input.length << 1)
function encode(buffer) {
var bi = BigInteger.fromBuffer(buffer)
var result = new Buffer(buffer.length << 1)

var i = result.length - 1
while (bi.compareTo(BigInteger.ZERO) > 0) {
var remainder = bi.mod(base)
bi = bi.divide(base)
while (bi.signum() > 0) {
var remainder = bi.mod(BASE)
bi = bi.divide(BASE)

result[i] = ALPHABET_BUF[remainder.intValue()]
i--
}

// deal with leading zeros
var j = 0
while (input[j] === 0) {
while (buffer[j] === 0) {
result[i] = ALPHABET_BUF[0]
j++
i--
}

return result.slice(i + 1, result.length).toString()
return result.slice(i + 1, result.length).toString('ascii')
}

function decode(string) {
if (string.length === 0) return new Buffer(0)

function decode (input) {
var num = BigInteger.valueOf(0);
var leadingZero = 0;
var seenOther = false;
for (var i = 0; i < input.length ; ++i) {
var ch = input[i];
var p = LOOKUP[ch];
var num = BigInteger.ZERO

// if we encounter an invalid character, decoding fails
if (p === undefined) {
throw new Error('invalid base58 string: ' + input);
}
for (var i = 0; i < string.length; i++) {
num = num.multiply(BASE)

num = num.multiply(base).add(BigInteger.valueOf(p));
var figure = ALPHABET_MAP[string.charAt(i)]
assert.notEqual(figure, undefined, 'Non-base58 character')

if (ch == ALPHABET[0] && !seenOther) {
++leadingZero;
}
else {
seenOther = true;
}
num = num.add(figure)
}

var bytes = num.toByteArrayUnsigned();

// remove leading zeros
while (leadingZero-- > 0) {
bytes.unshift(0);
// deal with leading zeros
var j = 0
while ((j < string.length) && (string[j] === ALPHABET[0])) {
j++
}

return new Buffer(bytes);
var buffer = num.toBuffer()
var leadingZeros = new Buffer(j)
leadingZeros.fill(0)

return Buffer.concat([leadingZeros, buffer])
}

module.exports = {
encode: encode,
decode: decode
}
2 changes: 1 addition & 1 deletion test/bs58.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('base58', function() {
it('throws on ' + f.description, function() {
assert.throws(function() {
base58.decode(f.string)
}, /invalid base58 string/)
}, /Non-base58 character/)
})
})
})
Expand Down

0 comments on commit 129c71d

Please sign in to comment.