123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import { arrayify, BytesLike } from "@ethersproject/bytes";
- import { defineReadOnly } from "@ethersproject/properties";
- export class BaseX {
- readonly alphabet: string;
- readonly base: number;
- _alphabetMap: { [ character: string ]: number };
- _leader: string;
- constructor(alphabet: string) {
- defineReadOnly(this, "alphabet", alphabet);
- defineReadOnly(this, "base", alphabet.length);
- defineReadOnly(this, "_alphabetMap", { });
- defineReadOnly(this, "_leader", alphabet.charAt(0));
-
- for (let i = 0; i < alphabet.length; i++) {
- this._alphabetMap[alphabet.charAt(i)] = i;
- }
- }
- encode(value: BytesLike): string {
- let source = arrayify(value);
- if (source.length === 0) { return ""; }
- let digits = [ 0 ]
- for (let i = 0; i < source.length; ++i) {
- let carry = source[i];
- for (let j = 0; j < digits.length; ++j) {
- carry += digits[j] << 8;
- digits[j] = carry % this.base;
- carry = (carry / this.base) | 0;
- }
- while (carry > 0) {
- digits.push(carry % this.base);
- carry = (carry / this.base) | 0;
- }
- }
- let string = ""
-
- for (let k = 0; source[k] === 0 && k < source.length - 1; ++k) {
- string += this._leader;
- }
-
- for (let q = digits.length - 1; q >= 0; --q) {
- string += this.alphabet[digits[q]];
- }
- return string;
- }
- decode(value: string): Uint8Array {
- if (typeof(value) !== "string") {
- throw new TypeError("Expected String");
- }
- let bytes: Array<number> = [];
- if (value.length === 0) { return new Uint8Array(bytes); }
- bytes.push(0);
- for (let i = 0; i < value.length; i++) {
- let byte = this._alphabetMap[value[i]];
- if (byte === undefined) {
- throw new Error("Non-base" + this.base + " character");
- }
- let carry = byte;
- for (let j = 0; j < bytes.length; ++j) {
- carry += bytes[j] * this.base;
- bytes[j] = carry & 0xff;
- carry >>= 8;
- }
- while (carry > 0) {
- bytes.push(carry & 0xff);
- carry >>= 8;
- }
- }
-
- for (let k = 0; value[k] === this._leader && k < value.length - 1; ++k) {
- bytes.push(0)
- }
- return arrayify(new Uint8Array(bytes.reverse()))
- }
- }
- const Base32 = new BaseX("abcdefghijklmnopqrstuvwxyz234567");
- const Base58 = new BaseX("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
- export { Base32, Base58 };
|