All files / ethers.js/src.ts/utils base58.ts

97.26% Statements 71/73
87.5% Branches 7/8
100% Functions 3/3
97.26% Lines 71/73

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 741x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 532800x 532800x 1x 1x 58x 58x 1x 532800x 532800x 532800x 532800x 1x 1x 1x 1x 1x 1x 1x 1x 1x 18000x 18000x 18000x 18000x 18000x 1998000x 1998000x 1998000x 18000x 18000x 18000x 18000x     18000x 18000x 18000x 1x 1x 1x 1x 1x 4800x 4800x 532800x 532800x 532800x 4800x 4800x  
/**
 *  The [Base58 Encoding](link-base58) scheme allows a **numeric** value
 *  to be encoded as a compact string using a radix of 58 using only
 *  alpha-numeric characters. Confusingly similar characters are omitted
 *  (i.e. ``"l0O"``).
 *
 *  Note that Base58 encodes a **numeric** value, not arbitrary bytes,
 *  since any zero-bytes on the left would get removed. To mitigate this
 *  issue most schemes that use Base58 choose specific high-order values
 *  to ensure non-zero prefixes.
 *
 *  @_subsection: api/utils:Base58 Encoding [about-base58]
 */
 
import { getBytes } from "./data.js";
import { assertArgument } from "./errors.js";
import { toBigInt } from "./maths.js";
 
import type { BytesLike } from "./index.js";
 
 
const Alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
let Lookup: null | Record<string, bigint> = null;
 
function getAlpha(letter: string): bigint {
    if (Lookup == null) {
        Lookup = { };
        for (let i = 0; i < Alphabet.length; i++) {
            Lookup[Alphabet[i]] = BigInt(i);
        }
    }
    const result = Lookup[letter];
    assertArgument(result != null, `invalid base58 value`, "letter", letter);
    return result;
}
 
 
const BN_0 = BigInt(0);
const BN_58 = BigInt(58);
 
/**
 *  Encode %%value%% as a Base58-encoded string.
 */
export function encodeBase58(_value: BytesLike): string {
    const bytes = getBytes(_value);
 
    let value = toBigInt(bytes);
    let result = "";
    while (value) {
        result = Alphabet[Number(value % BN_58)] + result;
        value /= BN_58;
    }
 
    // Account for leading padding zeros
    for (let i = 0; i < bytes.length; i++) {
        if (bytes[i]) { break; }
        result = Alphabet[0] + result;
    }
 
    return result;
}
 
/**
 *  Decode the Base58-encoded %%value%%.
 */
export function decodeBase58(value: string): bigint {
    let result = BN_0;
    for (let i = 0; i < value.length; i++) {
        result *= BN_58;
        result += getAlpha(value[i]);
    }
    return result;
}