@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
87 lines (67 loc) • 2.21 kB
JavaScript
import { assert } from "../../assert.js";
const base58_alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
const scratch = new Uint8Array(256);
/**
* Using bitcoin-inspired base58 encoding
* Primarily intended for UUID compression
* @param {Uint8Array} source
* @param {number} offset
* @param {number} byte_count
* @returns {string}
*/
export function base58_encode(
source,
offset,
byte_count
) {
// ported from the bitcoin's C codebase: https://github.com/bitcoin/bitcoin/blob/08a7316c144f9f2516db8fa62400893f4358c5ae/src/base58.cpp#L71
if (byte_count === 0) {
return "";
}
// Skip & count leading zeroes.
let zeroes = 0
let length = 0
let pbegin = offset
const pend = offset + byte_count
while (pbegin !== pend && source[pbegin] === 0) {
pbegin++
zeroes++
}
// Allocate enough space in big-endian base58 representation.
const size = ((pend - pbegin) * 138 / 100 + 1) >>> 0; /// log(256) / log(58), rounded up.
// use scratch if possible to avoid allocation
const b58 = (size <= scratch.length) ? scratch : new Uint8Array(size);
// Process the bytes.
while (pbegin !== pend) {
let carry = source[pbegin]
// Apply "b58 = b58 * 256 + ch".
let i = 0
for (
let it1 = size - 1;
(carry !== 0 || i < length) && (it1 !== -1);
it1--, i++
) {
carry += (256 * b58[it1]) >>> 0;
b58[it1] = (carry % 58) >>> 0;
carry = (carry / 58) >>> 0;
}
assert.equal(carry, 0, 'carry must be zero');
length = i;
pbegin++;
}
// Skip leading zeroes in base58 result.
let it2 = size - length
while (it2 !== size && b58[it2] === 0) {
it2++
}
// Translate the result into a string.
let str = base58_alphabet.charAt(0).repeat(zeroes)
for (; it2 < size; ++it2) {
str += base58_alphabet.charAt(b58[it2])
}
if (b58 === scratch) {
// clear out scratch
scratch.fill(0);
}
return str;
}