@wtasnorg/node-lib 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/changelog.txt +14 -0
  2. package/docs/README.md +12 -0
  3. package/docs/docs.json +1438 -211
  4. package/docs/functions/createFindDirectories.md +1 -1
  5. package/docs/functions/decode.md +1 -1
  6. package/docs/functions/decode32.md +49 -0
  7. package/docs/functions/decode58.md +49 -0
  8. package/docs/functions/decode85.md +49 -0
  9. package/docs/functions/encode.md +1 -1
  10. package/docs/functions/encode32.md +45 -0
  11. package/docs/functions/encode58.md +45 -0
  12. package/docs/functions/encode85.md +45 -0
  13. package/docs/functions/hello.md +1 -1
  14. package/docs/functions/parseUserAgent.md +1 -1
  15. package/docs/functions/pojo.md +1 -1
  16. package/docs/interfaces/FileSystemDependencies.md +3 -3
  17. package/docs/interfaces/FindDirectoriesOptions.md +5 -5
  18. package/docs/interfaces/UserAgentInfo.md +6 -6
  19. package/docs/type-aliases/Base32CharsetType.md +13 -0
  20. package/docs/type-aliases/Base58CharsetType.md +13 -0
  21. package/docs/type-aliases/Base64CharsetType.md +1 -1
  22. package/docs/type-aliases/Base85CharsetType.md +13 -0
  23. package/docs/variables/Base32Charset.md +16 -0
  24. package/docs/variables/Base58Charset.md +16 -0
  25. package/docs/variables/Base64Charset.md +1 -1
  26. package/docs/variables/Base85Charset.md +16 -0
  27. package/package.json +41 -1
  28. package/readme.txt +12 -0
  29. package/src/base32.d.ts +58 -0
  30. package/src/base32.js +143 -0
  31. package/src/base32.test.d.ts +2 -0
  32. package/src/base32.test.js +121 -0
  33. package/src/base32.test.ts +144 -0
  34. package/src/base32.ts +169 -0
  35. package/src/base58.d.ts +58 -0
  36. package/src/base58.js +155 -0
  37. package/src/base58.test.d.ts +2 -0
  38. package/src/base58.test.js +108 -0
  39. package/src/base58.test.ts +128 -0
  40. package/src/base58.ts +177 -0
  41. package/src/base85.d.ts +58 -0
  42. package/src/base85.js +173 -0
  43. package/src/base85.test.d.ts +2 -0
  44. package/src/base85.test.js +107 -0
  45. package/src/base85.test.ts +125 -0
  46. package/src/base85.ts +199 -0
  47. package/src/index.d.ts +8 -2
  48. package/src/index.js +4 -1
  49. package/src/index.ts +20 -2
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Base32 encoding/decoding with multiple charset variants.
3
+ * Base32 is case-insensitive and useful for human-readable encoding (TOTP codes).
4
+ * @module base32
5
+ */
6
+ /**
7
+ * Available Base32 charset variants.
8
+ * - `rfc4648`: Standard RFC 4648 alphabet (A-Z, 2-7)
9
+ * - `hex`: Extended hex alphabet (0-9, A-V)
10
+ * - `crockford`: Douglas Crockford's alphabet (excludes I, L, O, U)
11
+ */
12
+ declare const Base32Charset: readonly ["rfc4648", "hex", "crockford"];
13
+ /**
14
+ * Base32 charset type.
15
+ */
16
+ type Base32CharsetType = (typeof Base32Charset)[number];
17
+ /**
18
+ * Encode a string to Base32.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { encode32 } from "./base32.js";
23
+ *
24
+ * encode32("Hello");
25
+ * // => "JBSWY3DP"
26
+ *
27
+ * encode32("test", "hex");
28
+ * // => "EHMP6SS="
29
+ * ```
30
+ *
31
+ * @param input - The string to encode.
32
+ * @param charset - The charset variant to use (default: "rfc4648").
33
+ * @returns The Base32 encoded string.
34
+ */
35
+ declare function encode32(input: string, charset?: Base32CharsetType): string;
36
+ /**
37
+ * Decode a Base32 string.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { decode32 } from "./base32.js";
42
+ *
43
+ * decode32("JBSWY3DP");
44
+ * // => "Hello"
45
+ *
46
+ * decode32("EHMP6SS=", "hex");
47
+ * // => "test"
48
+ * ```
49
+ *
50
+ * @param input - The Base32 encoded string.
51
+ * @param charset - The charset variant to use (default: "rfc4648").
52
+ * @returns The decoded string.
53
+ * @throws Error if the input contains invalid characters.
54
+ */
55
+ declare function decode32(input: string, charset?: Base32CharsetType): string;
56
+ export { encode32, decode32, Base32Charset };
57
+ export type { Base32CharsetType };
58
+ //# sourceMappingURL=base32.d.ts.map
package/src/base32.js ADDED
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Base32 encoding/decoding with multiple charset variants.
3
+ * Base32 is case-insensitive and useful for human-readable encoding (TOTP codes).
4
+ * @module base32
5
+ */
6
+ /**
7
+ * Available Base32 charset variants.
8
+ * - `rfc4648`: Standard RFC 4648 alphabet (A-Z, 2-7)
9
+ * - `hex`: Extended hex alphabet (0-9, A-V)
10
+ * - `crockford`: Douglas Crockford's alphabet (excludes I, L, O, U)
11
+ */
12
+ const Base32Charset = ["rfc4648", "hex", "crockford"];
13
+ /**
14
+ * Charset alphabets for Base32 variants.
15
+ */
16
+ const CHARSETS = {
17
+ rfc4648: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
18
+ hex: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
19
+ crockford: "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
20
+ };
21
+ /**
22
+ * Padding character for Base32 encoding.
23
+ */
24
+ const PAD = "=";
25
+ /**
26
+ * Build a reverse lookup table for decoding.
27
+ * @param alphabet - The 32-character alphabet string.
28
+ * @param caseInsensitive - Whether to add lowercase mappings.
29
+ * @returns Map of character to index.
30
+ */
31
+ function buildDecodeTable(alphabet, caseInsensitive = true) {
32
+ const table = new Map();
33
+ for (let i = 0; i < alphabet.length; i++) {
34
+ const char = alphabet[i];
35
+ if (char !== undefined) {
36
+ table.set(char, i);
37
+ if (caseInsensitive) {
38
+ table.set(char.toLowerCase(), i);
39
+ }
40
+ }
41
+ }
42
+ return table;
43
+ }
44
+ /**
45
+ * Pre-built decode tables for each charset.
46
+ */
47
+ const DECODE_TABLES = {
48
+ rfc4648: buildDecodeTable(CHARSETS.rfc4648),
49
+ hex: buildDecodeTable(CHARSETS.hex),
50
+ crockford: buildDecodeTable(CHARSETS.crockford)
51
+ };
52
+ /**
53
+ * Encode a string to Base32.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * import { encode32 } from "./base32.js";
58
+ *
59
+ * encode32("Hello");
60
+ * // => "JBSWY3DP"
61
+ *
62
+ * encode32("test", "hex");
63
+ * // => "EHMP6SS="
64
+ * ```
65
+ *
66
+ * @param input - The string to encode.
67
+ * @param charset - The charset variant to use (default: "rfc4648").
68
+ * @returns The Base32 encoded string.
69
+ */
70
+ function encode32(input, charset = "rfc4648") {
71
+ if (input === "") {
72
+ return "";
73
+ }
74
+ const alphabet = CHARSETS[charset];
75
+ const bytes = new TextEncoder().encode(input);
76
+ let result = "";
77
+ let buffer = 0;
78
+ let bitsInBuffer = 0;
79
+ for (const byte of bytes) {
80
+ buffer = (buffer << 8) | byte;
81
+ bitsInBuffer += 8;
82
+ while (bitsInBuffer >= 5) {
83
+ bitsInBuffer -= 5;
84
+ const index = (buffer >> bitsInBuffer) & 0x1f;
85
+ result += alphabet[index];
86
+ }
87
+ }
88
+ // Handle remaining bits
89
+ if (bitsInBuffer > 0) {
90
+ const index = (buffer << (5 - bitsInBuffer)) & 0x1f;
91
+ result += alphabet[index];
92
+ }
93
+ // Add padding to make length a multiple of 8
94
+ while (result.length % 8 !== 0) {
95
+ result += PAD;
96
+ }
97
+ return result;
98
+ }
99
+ /**
100
+ * Decode a Base32 string.
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * import { decode32 } from "./base32.js";
105
+ *
106
+ * decode32("JBSWY3DP");
107
+ * // => "Hello"
108
+ *
109
+ * decode32("EHMP6SS=", "hex");
110
+ * // => "test"
111
+ * ```
112
+ *
113
+ * @param input - The Base32 encoded string.
114
+ * @param charset - The charset variant to use (default: "rfc4648").
115
+ * @returns The decoded string.
116
+ * @throws Error if the input contains invalid characters.
117
+ */
118
+ function decode32(input, charset = "rfc4648") {
119
+ if (input === "") {
120
+ return "";
121
+ }
122
+ const decodeTable = DECODE_TABLES[charset];
123
+ // Remove padding
124
+ const cleanInput = input.replace(/=+$/, "");
125
+ const bytes = [];
126
+ let buffer = 0;
127
+ let bitsInBuffer = 0;
128
+ for (const char of cleanInput) {
129
+ const value = decodeTable.get(char);
130
+ if (value === undefined) {
131
+ throw new Error(`Invalid Base32 character: ${char}`);
132
+ }
133
+ buffer = (buffer << 5) | value;
134
+ bitsInBuffer += 5;
135
+ if (bitsInBuffer >= 8) {
136
+ bitsInBuffer -= 8;
137
+ bytes.push((buffer >> bitsInBuffer) & 0xff);
138
+ }
139
+ }
140
+ return new TextDecoder().decode(new Uint8Array(bytes));
141
+ }
142
+ export { encode32, decode32, Base32Charset };
143
+ //# sourceMappingURL=base32.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base32.test.d.ts.map
@@ -0,0 +1,121 @@
1
+ import { describe, it } from "node:test";
2
+ import { strictEqual, throws } from "node:assert";
3
+ import { encode32, decode32, Base32Charset } from "./base32.js";
4
+ describe("Base32 encode32", () => {
5
+ it("encodes empty string", () => {
6
+ strictEqual(encode32(""), "");
7
+ });
8
+ it("encodes 'Hello' with rfc4648 charset", () => {
9
+ strictEqual(encode32("Hello"), "JBSWY3DP");
10
+ });
11
+ it("encodes single character", () => {
12
+ strictEqual(encode32("A"), "IE======");
13
+ });
14
+ it("encodes two characters", () => {
15
+ strictEqual(encode32("AB"), "IFBA====");
16
+ });
17
+ it("encodes 'test'", () => {
18
+ strictEqual(encode32("test"), "ORSXG5A=");
19
+ });
20
+ it("encodes with hex charset", () => {
21
+ const rfc4648 = encode32("test", "rfc4648");
22
+ const hex = encode32("test", "hex");
23
+ strictEqual(rfc4648 !== hex, true);
24
+ });
25
+ it("encodes with crockford charset", () => {
26
+ const rfc4648 = encode32("test", "rfc4648");
27
+ const crockford = encode32("test", "crockford");
28
+ strictEqual(rfc4648 !== crockford, true);
29
+ });
30
+ it("encodes UTF-8 characters", () => {
31
+ const input = "こんにちは";
32
+ const encoded = encode32(input);
33
+ const decoded = decode32(encoded);
34
+ strictEqual(decoded, input);
35
+ });
36
+ });
37
+ describe("Base32 decode32", () => {
38
+ it("decodes empty string", () => {
39
+ strictEqual(decode32(""), "");
40
+ });
41
+ it("decodes 'JBSWY3DP' to 'Hello'", () => {
42
+ strictEqual(decode32("JBSWY3DP"), "Hello");
43
+ });
44
+ it("decodes single character with padding", () => {
45
+ strictEqual(decode32("IE======"), "A");
46
+ });
47
+ it("decodes 'ORSXG5A=' to 'test'", () => {
48
+ strictEqual(decode32("ORSXG5A="), "test");
49
+ });
50
+ it("decodes without padding", () => {
51
+ strictEqual(decode32("JBSWY3DP"), "Hello");
52
+ });
53
+ it("decodes lowercase (case-insensitive)", () => {
54
+ strictEqual(decode32("jbswy3dp"), "Hello");
55
+ });
56
+ it("decodes mixed case", () => {
57
+ strictEqual(decode32("JbSwY3Dp"), "Hello");
58
+ });
59
+ it("throws on invalid character", () => {
60
+ throws(() => decode32("!!!"), /Invalid Base32 character/);
61
+ });
62
+ });
63
+ describe("Base32 round-trip", () => {
64
+ const testCases = [
65
+ "",
66
+ "a",
67
+ "ab",
68
+ "abc",
69
+ "abcd",
70
+ "abcde",
71
+ "Hello, World!",
72
+ "The quick brown fox jumps over the lazy dog",
73
+ "こんにちは世界",
74
+ "🎉🚀✨",
75
+ "1234567890"
76
+ ];
77
+ for (const charset of Base32Charset) {
78
+ describe(`charset: ${charset}`, () => {
79
+ for (const input of testCases) {
80
+ it(`round-trips: ${JSON.stringify(input)}`, () => {
81
+ const encoded = encode32(input, charset);
82
+ const decoded = decode32(encoded, charset);
83
+ strictEqual(decoded, input);
84
+ });
85
+ }
86
+ });
87
+ }
88
+ });
89
+ describe("Base32Charset", () => {
90
+ it("exports array with three charsets", () => {
91
+ strictEqual(Base32Charset.length, 3);
92
+ strictEqual(Base32Charset[0], "rfc4648");
93
+ strictEqual(Base32Charset[1], "hex");
94
+ strictEqual(Base32Charset[2], "crockford");
95
+ });
96
+ it("charset type works correctly", () => {
97
+ const cs = "hex";
98
+ strictEqual(encode32("test", cs), encode32("test", "hex"));
99
+ });
100
+ });
101
+ describe("Base32 RFC 4648 test vectors", () => {
102
+ // Test vectors from RFC 4648
103
+ const vectors = [
104
+ ["", ""],
105
+ ["f", "MY======"],
106
+ ["fo", "MZXQ===="],
107
+ ["foo", "MZXW6==="],
108
+ ["foob", "MZXW6YQ="],
109
+ ["fooba", "MZXW6YTB"],
110
+ ["foobar", "MZXW6YTBOI======"]
111
+ ];
112
+ for (const [input, expected] of vectors) {
113
+ it(`encodes "${input}" to "${expected}"`, () => {
114
+ strictEqual(encode32(input), expected);
115
+ });
116
+ it(`decodes "${expected}" to "${input}"`, () => {
117
+ strictEqual(decode32(expected), input);
118
+ });
119
+ }
120
+ });
121
+ //# sourceMappingURL=base32.test.js.map
@@ -0,0 +1,144 @@
1
+ import { describe, it } from "node:test";
2
+ import { strictEqual, throws } from "node:assert";
3
+ import { encode32, decode32, Base32Charset } from "./base32.js";
4
+ import type { Base32CharsetType } from "./base32.js";
5
+
6
+ describe("Base32 encode32", () => {
7
+ it("encodes empty string", () => {
8
+ strictEqual(encode32(""), "");
9
+ });
10
+
11
+ it("encodes 'Hello' with rfc4648 charset", () => {
12
+ strictEqual(encode32("Hello"), "JBSWY3DP");
13
+ });
14
+
15
+ it("encodes single character", () => {
16
+ strictEqual(encode32("A"), "IE======");
17
+ });
18
+
19
+ it("encodes two characters", () => {
20
+ strictEqual(encode32("AB"), "IFBA====");
21
+ });
22
+
23
+ it("encodes 'test'", () => {
24
+ strictEqual(encode32("test"), "ORSXG5A=");
25
+ });
26
+
27
+ it("encodes with hex charset", () => {
28
+ const rfc4648 = encode32("test", "rfc4648");
29
+ const hex = encode32("test", "hex");
30
+ strictEqual(rfc4648 !== hex, true);
31
+ });
32
+
33
+ it("encodes with crockford charset", () => {
34
+ const rfc4648 = encode32("test", "rfc4648");
35
+ const crockford = encode32("test", "crockford");
36
+ strictEqual(rfc4648 !== crockford, true);
37
+ });
38
+
39
+ it("encodes UTF-8 characters", () => {
40
+ const input = "こんにちは";
41
+ const encoded = encode32(input);
42
+ const decoded = decode32(encoded);
43
+ strictEqual(decoded, input);
44
+ });
45
+ });
46
+
47
+ describe("Base32 decode32", () => {
48
+ it("decodes empty string", () => {
49
+ strictEqual(decode32(""), "");
50
+ });
51
+
52
+ it("decodes 'JBSWY3DP' to 'Hello'", () => {
53
+ strictEqual(decode32("JBSWY3DP"), "Hello");
54
+ });
55
+
56
+ it("decodes single character with padding", () => {
57
+ strictEqual(decode32("IE======"), "A");
58
+ });
59
+
60
+ it("decodes 'ORSXG5A=' to 'test'", () => {
61
+ strictEqual(decode32("ORSXG5A="), "test");
62
+ });
63
+
64
+ it("decodes without padding", () => {
65
+ strictEqual(decode32("JBSWY3DP"), "Hello");
66
+ });
67
+
68
+ it("decodes lowercase (case-insensitive)", () => {
69
+ strictEqual(decode32("jbswy3dp"), "Hello");
70
+ });
71
+
72
+ it("decodes mixed case", () => {
73
+ strictEqual(decode32("JbSwY3Dp"), "Hello");
74
+ });
75
+
76
+ it("throws on invalid character", () => {
77
+ throws(() => decode32("!!!"), /Invalid Base32 character/);
78
+ });
79
+ });
80
+
81
+ describe("Base32 round-trip", () => {
82
+ const testCases = [
83
+ "",
84
+ "a",
85
+ "ab",
86
+ "abc",
87
+ "abcd",
88
+ "abcde",
89
+ "Hello, World!",
90
+ "The quick brown fox jumps over the lazy dog",
91
+ "こんにちは世界",
92
+ "🎉🚀✨",
93
+ "1234567890"
94
+ ];
95
+
96
+ for (const charset of Base32Charset) {
97
+ describe(`charset: ${charset}`, () => {
98
+ for (const input of testCases) {
99
+ it(`round-trips: ${JSON.stringify(input)}`, () => {
100
+ const encoded = encode32(input, charset);
101
+ const decoded = decode32(encoded, charset);
102
+ strictEqual(decoded, input);
103
+ });
104
+ }
105
+ });
106
+ }
107
+ });
108
+
109
+ describe("Base32Charset", () => {
110
+ it("exports array with three charsets", () => {
111
+ strictEqual(Base32Charset.length, 3);
112
+ strictEqual(Base32Charset[0], "rfc4648");
113
+ strictEqual(Base32Charset[1], "hex");
114
+ strictEqual(Base32Charset[2], "crockford");
115
+ });
116
+
117
+ it("charset type works correctly", () => {
118
+ const cs: Base32CharsetType = "hex";
119
+ strictEqual(encode32("test", cs), encode32("test", "hex"));
120
+ });
121
+ });
122
+
123
+ describe("Base32 RFC 4648 test vectors", () => {
124
+ // Test vectors from RFC 4648
125
+ const vectors: [string, string][] = [
126
+ ["", ""],
127
+ ["f", "MY======"],
128
+ ["fo", "MZXQ===="],
129
+ ["foo", "MZXW6==="],
130
+ ["foob", "MZXW6YQ="],
131
+ ["fooba", "MZXW6YTB"],
132
+ ["foobar", "MZXW6YTBOI======"]
133
+ ];
134
+
135
+ for (const [input, expected] of vectors) {
136
+ it(`encodes "${input}" to "${expected}"`, () => {
137
+ strictEqual(encode32(input), expected);
138
+ });
139
+
140
+ it(`decodes "${expected}" to "${input}"`, () => {
141
+ strictEqual(decode32(expected), input);
142
+ });
143
+ }
144
+ });
package/src/base32.ts ADDED
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Base32 encoding/decoding with multiple charset variants.
3
+ * Base32 is case-insensitive and useful for human-readable encoding (TOTP codes).
4
+ * @module base32
5
+ */
6
+
7
+ /**
8
+ * Available Base32 charset variants.
9
+ * - `rfc4648`: Standard RFC 4648 alphabet (A-Z, 2-7)
10
+ * - `hex`: Extended hex alphabet (0-9, A-V)
11
+ * - `crockford`: Douglas Crockford's alphabet (excludes I, L, O, U)
12
+ */
13
+ const Base32Charset = ["rfc4648", "hex", "crockford"] as const;
14
+
15
+ /**
16
+ * Base32 charset type.
17
+ */
18
+ type Base32CharsetType = (typeof Base32Charset)[number];
19
+
20
+ /**
21
+ * Charset alphabets for Base32 variants.
22
+ */
23
+ const CHARSETS: Record<Base32CharsetType, string> = {
24
+ rfc4648: "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",
25
+ hex: "0123456789ABCDEFGHIJKLMNOPQRSTUV",
26
+ crockford: "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
27
+ };
28
+
29
+ /**
30
+ * Padding character for Base32 encoding.
31
+ */
32
+ const PAD = "=";
33
+
34
+ /**
35
+ * Build a reverse lookup table for decoding.
36
+ * @param alphabet - The 32-character alphabet string.
37
+ * @param caseInsensitive - Whether to add lowercase mappings.
38
+ * @returns Map of character to index.
39
+ */
40
+ function buildDecodeTable(alphabet: string, caseInsensitive = true): Map<string, number> {
41
+ const table = new Map<string, number>();
42
+ for (let i = 0; i < alphabet.length; i++) {
43
+ const char = alphabet[i];
44
+ if (char !== undefined) {
45
+ table.set(char, i);
46
+ if (caseInsensitive) {
47
+ table.set(char.toLowerCase(), i);
48
+ }
49
+ }
50
+ }
51
+ return table;
52
+ }
53
+
54
+ /**
55
+ * Pre-built decode tables for each charset.
56
+ */
57
+ const DECODE_TABLES: Record<Base32CharsetType, Map<string, number>> = {
58
+ rfc4648: buildDecodeTable(CHARSETS.rfc4648),
59
+ hex: buildDecodeTable(CHARSETS.hex),
60
+ crockford: buildDecodeTable(CHARSETS.crockford)
61
+ };
62
+
63
+ /**
64
+ * Encode a string to Base32.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * import { encode32 } from "./base32.js";
69
+ *
70
+ * encode32("Hello");
71
+ * // => "JBSWY3DP"
72
+ *
73
+ * encode32("test", "hex");
74
+ * // => "EHMP6SS="
75
+ * ```
76
+ *
77
+ * @param input - The string to encode.
78
+ * @param charset - The charset variant to use (default: "rfc4648").
79
+ * @returns The Base32 encoded string.
80
+ */
81
+ function encode32(input: string, charset: Base32CharsetType = "rfc4648"): string {
82
+ if (input === "") {
83
+ return "";
84
+ }
85
+
86
+ const alphabet = CHARSETS[charset];
87
+ const bytes = new TextEncoder().encode(input);
88
+ let result = "";
89
+ let buffer = 0;
90
+ let bitsInBuffer = 0;
91
+
92
+ for (const byte of bytes) {
93
+ buffer = (buffer << 8) | byte;
94
+ bitsInBuffer += 8;
95
+
96
+ while (bitsInBuffer >= 5) {
97
+ bitsInBuffer -= 5;
98
+ const index = (buffer >> bitsInBuffer) & 0x1f;
99
+ result += alphabet[index];
100
+ }
101
+ }
102
+
103
+ // Handle remaining bits
104
+ if (bitsInBuffer > 0) {
105
+ const index = (buffer << (5 - bitsInBuffer)) & 0x1f;
106
+ result += alphabet[index];
107
+ }
108
+
109
+ // Add padding to make length a multiple of 8
110
+ while (result.length % 8 !== 0) {
111
+ result += PAD;
112
+ }
113
+
114
+ return result;
115
+ }
116
+
117
+ /**
118
+ * Decode a Base32 string.
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * import { decode32 } from "./base32.js";
123
+ *
124
+ * decode32("JBSWY3DP");
125
+ * // => "Hello"
126
+ *
127
+ * decode32("EHMP6SS=", "hex");
128
+ * // => "test"
129
+ * ```
130
+ *
131
+ * @param input - The Base32 encoded string.
132
+ * @param charset - The charset variant to use (default: "rfc4648").
133
+ * @returns The decoded string.
134
+ * @throws Error if the input contains invalid characters.
135
+ */
136
+ function decode32(input: string, charset: Base32CharsetType = "rfc4648"): string {
137
+ if (input === "") {
138
+ return "";
139
+ }
140
+
141
+ const decodeTable = DECODE_TABLES[charset];
142
+
143
+ // Remove padding
144
+ const cleanInput = input.replace(/=+$/, "");
145
+ const bytes: number[] = [];
146
+
147
+ let buffer = 0;
148
+ let bitsInBuffer = 0;
149
+
150
+ for (const char of cleanInput) {
151
+ const value = decodeTable.get(char);
152
+ if (value === undefined) {
153
+ throw new Error(`Invalid Base32 character: ${char}`);
154
+ }
155
+
156
+ buffer = (buffer << 5) | value;
157
+ bitsInBuffer += 5;
158
+
159
+ if (bitsInBuffer >= 8) {
160
+ bitsInBuffer -= 8;
161
+ bytes.push((buffer >> bitsInBuffer) & 0xff);
162
+ }
163
+ }
164
+
165
+ return new TextDecoder().decode(new Uint8Array(bytes));
166
+ }
167
+
168
+ export { encode32, decode32, Base32Charset };
169
+ export type { Base32CharsetType };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Base58 encoding/decoding with multiple charset variants.
3
+ * Base58 excludes visually ambiguous characters (0, O, I, l).
4
+ * @module base58
5
+ */
6
+ /**
7
+ * Available Base58 charset variants.
8
+ * - `bitcoin`: Bitcoin/IPFS alphabet (default)
9
+ * - `flickr`: Flickr short URLs (swaps case)
10
+ * - `ripple`: Ripple addresses
11
+ */
12
+ declare const Base58Charset: readonly ["bitcoin", "flickr", "ripple"];
13
+ /**
14
+ * Base58 charset type.
15
+ */
16
+ type Base58CharsetType = (typeof Base58Charset)[number];
17
+ /**
18
+ * Encode a string to Base58.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { encode58 } from "./base58.js";
23
+ *
24
+ * encode58("Hello World");
25
+ * // => "JxF12TrwUP45BMd"
26
+ *
27
+ * encode58("Hello World", "flickr");
28
+ * // => "jXf12sRWto45bmD"
29
+ * ```
30
+ *
31
+ * @param input - The string to encode.
32
+ * @param charset - The charset variant to use (default: "bitcoin").
33
+ * @returns The Base58 encoded string.
34
+ */
35
+ declare function encode58(input: string, charset?: Base58CharsetType): string;
36
+ /**
37
+ * Decode a Base58 string.
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { decode58 } from "./base58.js";
42
+ *
43
+ * decode58("JxF12TrwUP45BMd");
44
+ * // => "Hello World"
45
+ *
46
+ * decode58("jXf12sRWto45bmD", "flickr");
47
+ * // => "Hello World"
48
+ * ```
49
+ *
50
+ * @param input - The Base58 encoded string.
51
+ * @param charset - The charset variant to use (default: "bitcoin").
52
+ * @returns The decoded string.
53
+ * @throws Error if the input contains invalid characters.
54
+ */
55
+ declare function decode58(input: string, charset?: Base58CharsetType): string;
56
+ export { encode58, decode58, Base58Charset };
57
+ export type { Base58CharsetType };
58
+ //# sourceMappingURL=base58.d.ts.map