base58.js 1.9 KB

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