@nakanoaas/uuid58 1.2.2 → 2.0.0
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.
- package/README.md +87 -17
- package/dist/index.cjs +233 -86
- package/dist/index.d.cts +144 -50
- package/dist/index.d.ts +144 -50
- package/dist/index.js +230 -87
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -16,57 +16,37 @@
|
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
const UUID58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
19
|
+
// internal.ts
|
|
20
|
+
const MAX_PREVIEW_LENGTH = 40;
|
|
19
21
|
/**
|
|
20
22
|
* @internal
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
+
* 58^9, the largest power of 58 below 2^53. A 9-digit Base58 chunk therefore
|
|
24
|
+
* fits in a Number, so most digit arithmetic can avoid slow BigInt division.
|
|
23
25
|
*/
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
const BASE58_CHUNK = 7427658739644928n;
|
|
27
|
+
/** Appends `digits` Base58 digits of `value` (most significant first). */
|
|
28
|
+
function appendDigits(out, value, digits) {
|
|
29
|
+
let chunk = "";
|
|
30
|
+
for (let i = 0; i < digits; i++) {
|
|
31
|
+
const quotient = Math.floor(value / 58);
|
|
32
|
+
chunk = UUID58_ALPHABET[value - quotient * 58] + chunk;
|
|
33
|
+
value = quotient;
|
|
34
|
+
}
|
|
35
|
+
return out + chunk;
|
|
36
|
+
}
|
|
27
37
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* This regex ensures that a string:
|
|
31
|
-
* - Contains exactly 22 characters
|
|
32
|
-
* - Uses only characters from the Base58 alphabet
|
|
33
|
-
*
|
|
34
|
-
* **Note:** This regex does NOT validate that the decoded value fits within
|
|
35
|
-
* 128 bits (UUID size). For complete validation including 128-bit range
|
|
36
|
-
* checking, use {@link isUuid58} instead.
|
|
38
|
+
* @internal
|
|
39
|
+
* Encodes an unsigned 128-bit integer as a 22-character Base58 string.
|
|
37
40
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* const isValid = UUID58_REGEX.test("XDY9dmBbcMBXqcRvYw8xJ2"); // true
|
|
41
|
-
* const isValid = UUID58_REGEX.test("invalid"); // false
|
|
42
|
-
* const isValid = UUID58_REGEX.test("123"); // false (too short)
|
|
43
|
-
* ```
|
|
41
|
+
* The value is split into 4 + 9 + 9 digit chunks with two BigInt divisions,
|
|
42
|
+
* instead of 22 BigInt divisions (one per digit).
|
|
44
43
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* A valid UUID58 string must:
|
|
51
|
-
* - Be exactly 22 characters long
|
|
52
|
-
* - Contain only characters from the Base58 alphabet
|
|
53
|
-
* - Decode to a value that fits within 128 bits (UUID size)
|
|
54
|
-
*
|
|
55
|
-
* @param uuid58 - The string to check
|
|
56
|
-
* @returns `true` if the string is a valid UUID58 string, `false` otherwise
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* isUuid58("XDY9dmBbcMBXqcRvYw8xJ2"); // true
|
|
61
|
-
* isUuid58("invalid"); // false
|
|
62
|
-
* isUuid58("O0lI"); // false (contains invalid characters)
|
|
63
|
-
* ```
|
|
64
|
-
*/
|
|
65
|
-
function isUuid58(uuid58) {
|
|
66
|
-
return UUID58_REGEX.test(uuid58) && uuid58 <= MAX_UUID58;
|
|
44
|
+
function encodeUint128(num) {
|
|
45
|
+
const low = Number(num % BASE58_CHUNK);
|
|
46
|
+
num /= BASE58_CHUNK;
|
|
47
|
+
const mid = Number(num % BASE58_CHUNK);
|
|
48
|
+
return appendDigits(appendDigits(appendDigits("", Number(num / BASE58_CHUNK), 4), mid, 9), low, 9);
|
|
67
49
|
}
|
|
68
|
-
// internal.ts
|
|
69
|
-
const MAX_PREVIEW_LENGTH = 40;
|
|
70
50
|
/**
|
|
71
51
|
* @internal
|
|
72
52
|
* Formats untrusted input for inclusion in an error message.
|
|
@@ -80,16 +60,48 @@ function previewInput(input) {
|
|
|
80
60
|
}
|
|
81
61
|
// decode.ts
|
|
82
62
|
var _Uuid58DecodeError;
|
|
83
|
-
const
|
|
84
|
-
for (let i = 0; i < 58; i++)
|
|
63
|
+
const BASE58_INDEX = (/* @__PURE__ */ new Int8Array(128)).fill(-1);
|
|
64
|
+
for (let i = 0; i < 58; i++) BASE58_INDEX[UUID58_ALPHABET.charCodeAt(i)] = i;
|
|
65
|
+
const MAX_UINT128 = (1n << 128n) - 1n;
|
|
85
66
|
/**
|
|
86
|
-
* Error thrown when an invalid
|
|
87
|
-
*
|
|
67
|
+
* Error thrown when an invalid uuid58 string is provided for decoding.
|
|
68
|
+
* Its {@link Uuid58DecodeError.kind | kind} tells why.
|
|
88
69
|
*/
|
|
89
|
-
var Uuid58DecodeError = class extends Error {
|
|
70
|
+
var Uuid58DecodeError = class extends Error {
|
|
71
|
+
constructor(message, kind) {
|
|
72
|
+
super(message);
|
|
73
|
+
this.kind = kind;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
90
76
|
_Uuid58DecodeError = Uuid58DecodeError;
|
|
91
77
|
_Uuid58DecodeError.prototype.name = "Uuid58DecodeError";
|
|
92
78
|
/**
|
|
79
|
+
* @internal
|
|
80
|
+
* Decodes a uuid58 string to an unsigned 128-bit integer, checking length,
|
|
81
|
+
* then characters, then range (specification, Section 4).
|
|
82
|
+
*/
|
|
83
|
+
function decodeUint128(uuid58) {
|
|
84
|
+
if (uuid58.length !== 22) return new Uuid58DecodeError(`Expected Base58 string of length 22, but received string of length ${uuid58.length}: ${previewInput(uuid58)}`, "invalid_length");
|
|
85
|
+
let num = 0n;
|
|
86
|
+
for (let start = 0; start < 22;) {
|
|
87
|
+
const end = start === 0 ? 4 : start + 9;
|
|
88
|
+
let chunk = 0;
|
|
89
|
+
for (let i = start; i < end; i++) {
|
|
90
|
+
const code = uuid58.charCodeAt(i);
|
|
91
|
+
const index = code < 128 ? BASE58_INDEX[code] : -1;
|
|
92
|
+
if (index < 0) {
|
|
93
|
+
const char = String.fromCodePoint(uuid58.codePointAt(i));
|
|
94
|
+
return new Uuid58DecodeError(`Invalid Base58 character ${JSON.stringify(char)} found in input: ${previewInput(uuid58)}`, "invalid_character");
|
|
95
|
+
}
|
|
96
|
+
chunk = chunk * 58 + index;
|
|
97
|
+
}
|
|
98
|
+
num = num * BASE58_CHUNK + BigInt(chunk);
|
|
99
|
+
start = end;
|
|
100
|
+
}
|
|
101
|
+
if (num > MAX_UINT128) return new Uuid58DecodeError(`Decoded value exceeds 128 bits of UUID: ${previewInput(uuid58)}`, "overflow");
|
|
102
|
+
return num;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
93
105
|
* Converts a 22-character Base58-encoded string back to a standard UUID format, but instead of
|
|
94
106
|
* throwing an error for invalid input, it returns an `Uuid58DecodeError`
|
|
95
107
|
* instance.
|
|
@@ -102,19 +114,13 @@ _Uuid58DecodeError.prototype.name = "Uuid58DecodeError";
|
|
|
102
114
|
* @example
|
|
103
115
|
* ```typescript
|
|
104
116
|
* const uuid = uuid58DecodeSafe("XDY9dmBbcMBXqcRvYw8xJ2"); // returns "f4b247fd-1f87-45d4-aa06-1c6fc0a8dfaf"
|
|
105
|
-
* const error = uuid58DecodeSafe("invalid"); // returns Uuid58DecodeError
|
|
117
|
+
* const error = uuid58DecodeSafe("invalid"); // returns Uuid58DecodeError (kind: "invalid_length")
|
|
106
118
|
* ```
|
|
107
119
|
*/
|
|
108
120
|
function uuid58DecodeSafe(uuid58) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
for (const char of uuid58) {
|
|
112
|
-
const index = BASE58_MAP[char];
|
|
113
|
-
if (index === void 0) return new Uuid58DecodeError(`Invalid Base58 character ${JSON.stringify(char)} found in input: ${previewInput(uuid58)}`);
|
|
114
|
-
num = num * UUID58_LENGTH + index;
|
|
115
|
-
}
|
|
121
|
+
const num = decodeUint128(uuid58);
|
|
122
|
+
if (typeof num !== "bigint") return num;
|
|
116
123
|
const hex = num.toString(16).padStart(32, "0");
|
|
117
|
-
if (hex.length !== 32) return new Uuid58DecodeError(`Decoded value exceeds 128 bits of UUID: ${previewInput(uuid58)}`);
|
|
118
124
|
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
|
|
119
125
|
}
|
|
120
126
|
/**
|
|
@@ -137,18 +143,44 @@ function uuid58Decode(uuid58) {
|
|
|
137
143
|
// encode.ts
|
|
138
144
|
var _Uuid58EncodeError;
|
|
139
145
|
const HEX32_REGEX = /^[0-9a-f]{32}$/i;
|
|
146
|
+
const HYPHENATED_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
140
147
|
/**
|
|
141
|
-
* Error thrown when an invalid UUID string is provided for
|
|
142
|
-
*
|
|
148
|
+
* Error thrown when an invalid UUID string or byte array is provided for
|
|
149
|
+
* encoding. Its {@link Uuid58EncodeError.kind | kind} tells why.
|
|
143
150
|
*/
|
|
144
|
-
var Uuid58EncodeError = class extends Error {
|
|
151
|
+
var Uuid58EncodeError = class extends Error {
|
|
152
|
+
constructor(message, kind) {
|
|
153
|
+
super(message);
|
|
154
|
+
this.kind = kind;
|
|
155
|
+
}
|
|
156
|
+
};
|
|
145
157
|
_Uuid58EncodeError = Uuid58EncodeError;
|
|
146
158
|
_Uuid58EncodeError.prototype.name = "Uuid58EncodeError";
|
|
147
159
|
/**
|
|
160
|
+
* @internal
|
|
161
|
+
* Parses a UUID string in one of the two forms of the specification
|
|
162
|
+
* (Section 5.1) into an unsigned 128-bit integer.
|
|
163
|
+
*/
|
|
164
|
+
function parseUuidString(uuid) {
|
|
165
|
+
let hex;
|
|
166
|
+
if (uuid.length === 32) {
|
|
167
|
+
if (!HEX32_REGEX.test(uuid)) return new Uuid58EncodeError(`Invalid UUID: ${previewInput(uuid)} must be 32 hexadecimal digits`, "invalid_character");
|
|
168
|
+
hex = uuid;
|
|
169
|
+
} else if (uuid.length === 36) {
|
|
170
|
+
if (!HYPHENATED_REGEX.test(uuid)) return new Uuid58EncodeError(`Invalid UUID: ${previewInput(uuid)} must be in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`, "invalid_character");
|
|
171
|
+
hex = uuid.slice(0, 8) + uuid.slice(9, 13) + uuid.slice(14, 18) + uuid.slice(19, 23) + uuid.slice(24);
|
|
172
|
+
} else return new Uuid58EncodeError(`Invalid UUID length: expected 32 or 36 characters, got ${uuid.length} in ${previewInput(uuid)}`, "invalid_length");
|
|
173
|
+
return BigInt("0x" + hex);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
148
176
|
* Converts a standard UUID string to a 22-character Base58-encoded format, but instead of
|
|
149
177
|
* throwing an error for invalid input, it returns an `Uuid58EncodeError` instance.
|
|
150
178
|
*
|
|
151
|
-
*
|
|
179
|
+
* Only two forms are accepted, in any letter case: the hyphenated form
|
|
180
|
+
* (`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) and 32 hexadecimal digits. Braces,
|
|
181
|
+
* `urn:uuid:`, whitespace, and hyphens in other positions are rejected.
|
|
182
|
+
*
|
|
183
|
+
* @param uuid - The UUID string to encode (hyphenated, or 32 hexadecimal digits)
|
|
152
184
|
* @returns A 22-character Base58-encoded string, or an `Uuid58EncodeError` if the input is
|
|
153
185
|
* not a valid UUID
|
|
154
186
|
* @note This function does not throw; it returns the error object instead.
|
|
@@ -162,27 +194,20 @@ _Uuid58EncodeError.prototype.name = "Uuid58EncodeError";
|
|
|
162
194
|
* // Uppercase UUID is also accepted
|
|
163
195
|
* const base58 = uuid58EncodeSafe("F4B247FD-1F87-45D4-AA06-1C6FC0A8DFAF"); // returns "XDY9dmBbcMBXqcRvYw8xJ2"
|
|
164
196
|
* // Invalid UUID format
|
|
165
|
-
* const error = uuid58EncodeSafe("invalid"); // returns Uuid58EncodeError
|
|
197
|
+
* const error = uuid58EncodeSafe("invalid"); // returns Uuid58EncodeError (kind: "invalid_length")
|
|
166
198
|
* ```
|
|
167
199
|
*/
|
|
168
200
|
function uuid58EncodeSafe(uuid) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
if (!HEX32_REGEX.test(hex)) return new Uuid58EncodeError(`Invalid UUID format: ${previewInput(uuid)} contains non-hexadecimal characters`);
|
|
172
|
-
let num = BigInt("0x" + hex);
|
|
173
|
-
let encoded = "";
|
|
174
|
-
do {
|
|
175
|
-
encoded = UUID58_ALPHABET[Number(num % UUID58_LENGTH)] + encoded;
|
|
176
|
-
num /= UUID58_LENGTH;
|
|
177
|
-
} while (num > 0n);
|
|
178
|
-
return encoded.padStart(22, UUID58_ALPHABET[0]);
|
|
201
|
+
const num = parseUuidString(uuid);
|
|
202
|
+
return typeof num === "bigint" ? encodeUint128(num) : num;
|
|
179
203
|
}
|
|
180
204
|
/**
|
|
181
205
|
* Converts a standard UUID string to a 22-character Base58-encoded format.
|
|
182
206
|
*
|
|
183
|
-
* @param uuid - The UUID string to encode
|
|
184
|
-
* (
|
|
185
|
-
*
|
|
207
|
+
* @param uuid - The UUID string to encode, either hyphenated
|
|
208
|
+
* ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") or as 32 hexadecimal digits
|
|
209
|
+
* ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"). Hexadecimal digits may be in any case.
|
|
210
|
+
* Other forms, including hyphens in other positions, are rejected.
|
|
186
211
|
* @returns A 22-character Base58-encoded string representation of the UUID
|
|
187
212
|
* @throws {Uuid58EncodeError} If the input string is not a valid UUID format
|
|
188
213
|
*
|
|
@@ -201,7 +226,131 @@ function uuid58Encode(uuid) {
|
|
|
201
226
|
if (result instanceof Uuid58EncodeError) throw result;
|
|
202
227
|
return result;
|
|
203
228
|
}
|
|
229
|
+
// bytes.ts
|
|
230
|
+
/**
|
|
231
|
+
* Encodes 16 bytes, in big-endian (RFC 9562) order, as a 22-character uuid58
|
|
232
|
+
* string, but instead of throwing an error for invalid input, it returns an
|
|
233
|
+
* `Uuid58EncodeError` instance.
|
|
234
|
+
*
|
|
235
|
+
* @param bytes - The 16 bytes of the UUID
|
|
236
|
+
* @returns A 22-character uuid58 string, or an `Uuid58EncodeError` (kind
|
|
237
|
+
* `"invalid_length"`) if `bytes` is not exactly 16 bytes long
|
|
238
|
+
* @note This function does not throw; it returns the error object instead.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* const bytes = new Uint8Array(16); // nil UUID
|
|
243
|
+
* uuid58EncodeBytesSafe(bytes); // returns "1111111111111111111111"
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
function uuid58EncodeBytesSafe(bytes) {
|
|
247
|
+
if (bytes.length !== 16) return new Uuid58EncodeError(`Invalid byte length: expected 16 bytes, got ${bytes.length}`, "invalid_length");
|
|
248
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, 16);
|
|
249
|
+
return encodeUint128(view.getBigUint64(0) << 64n | view.getBigUint64(8));
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Encodes 16 bytes, in big-endian (RFC 9562) order, as a 22-character uuid58
|
|
253
|
+
* string.
|
|
254
|
+
*
|
|
255
|
+
* @param bytes - The 16 bytes of the UUID
|
|
256
|
+
* @returns A 22-character uuid58 string
|
|
257
|
+
* @throws {Uuid58EncodeError} If `bytes` is not exactly 16 bytes long
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* uuid58EncodeBytes(new Uint8Array(16)); // returns "1111111111111111111111"
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
function uuid58EncodeBytes(bytes) {
|
|
265
|
+
const result = uuid58EncodeBytesSafe(bytes);
|
|
266
|
+
if (result instanceof Uuid58EncodeError) throw result;
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Decodes a uuid58 string to 16 bytes in big-endian (RFC 9562) order, but
|
|
271
|
+
* instead of throwing an error for invalid input, it returns an
|
|
272
|
+
* `Uuid58DecodeError` instance.
|
|
273
|
+
*
|
|
274
|
+
* @param uuid58 - The 22-character uuid58 string to decode
|
|
275
|
+
* @returns A new 16-byte `Uint8Array`, or an `Uuid58DecodeError`
|
|
276
|
+
* @note This function does not throw; it returns the error object instead.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```typescript
|
|
280
|
+
* uuid58DecodeBytesSafe("1111111111111111111111"); // returns Uint8Array(16) of zeros
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
function uuid58DecodeBytesSafe(uuid58) {
|
|
284
|
+
const num = decodeUint128(uuid58);
|
|
285
|
+
if (typeof num !== "bigint") return num;
|
|
286
|
+
const bytes = /* @__PURE__ */ new Uint8Array(16);
|
|
287
|
+
const view = new DataView(bytes.buffer);
|
|
288
|
+
view.setBigUint64(0, num >> 64n);
|
|
289
|
+
view.setBigUint64(8, num & 18446744073709551615n);
|
|
290
|
+
return bytes;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Decodes a uuid58 string to 16 bytes in big-endian (RFC 9562) order.
|
|
294
|
+
*
|
|
295
|
+
* @param uuid58 - The 22-character uuid58 string to decode
|
|
296
|
+
* @returns A new 16-byte `Uint8Array`
|
|
297
|
+
* @throws {Uuid58DecodeError} If the input is not a valid uuid58 string
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const bytes = uuid58DecodeBytes("XDY9dmBbcMBXqcRvYw8xJ2");
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
function uuid58DecodeBytes(uuid58) {
|
|
305
|
+
const result = uuid58DecodeBytesSafe(uuid58);
|
|
306
|
+
if (result instanceof Uuid58DecodeError) throw result;
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
// check.ts
|
|
310
|
+
const MAX_UUID58 = "YcVfxkQb6JRzqk5kF2tNLv";
|
|
311
|
+
/**
|
|
312
|
+
* Regular expression pattern for validating UUID58 strings.
|
|
313
|
+
*
|
|
314
|
+
* This regex ensures that a string:
|
|
315
|
+
* - Contains exactly 22 characters
|
|
316
|
+
* - Uses only characters from the Base58 alphabet
|
|
317
|
+
*
|
|
318
|
+
* **Note:** This regex does NOT validate that the decoded value fits within
|
|
319
|
+
* 128 bits (UUID size). For complete validation including 128-bit range
|
|
320
|
+
* checking, use {@link isUuid58} instead.
|
|
321
|
+
*
|
|
322
|
+
* @example
|
|
323
|
+
* ```typescript
|
|
324
|
+
* const isValid = UUID58_REGEX.test("XDY9dmBbcMBXqcRvYw8xJ2"); // true
|
|
325
|
+
* const isValid = UUID58_REGEX.test("invalid"); // false
|
|
326
|
+
* const isValid = UUID58_REGEX.test("123"); // false (too short)
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
const UUID58_REGEX = /^[1-9A-HJ-NP-Za-km-z]{22}$/u;
|
|
330
|
+
/**
|
|
331
|
+
* Checks if a given string is a valid UUID58-encodable string.
|
|
332
|
+
* This function efficiently validates without performing full decoding.
|
|
333
|
+
*
|
|
334
|
+
* A valid UUID58 string must:
|
|
335
|
+
* - Be exactly 22 characters long
|
|
336
|
+
* - Contain only characters from the Base58 alphabet
|
|
337
|
+
* - Decode to a value that fits within 128 bits (UUID size)
|
|
338
|
+
*
|
|
339
|
+
* @param uuid58 - The string to check
|
|
340
|
+
* @returns `true` if the string is a valid UUID58 string, `false` otherwise
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* ```typescript
|
|
344
|
+
* isUuid58("XDY9dmBbcMBXqcRvYw8xJ2"); // true
|
|
345
|
+
* isUuid58("invalid"); // false
|
|
346
|
+
* isUuid58("O0lI"); // false (contains invalid characters)
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
function isUuid58(uuid58) {
|
|
350
|
+
return UUID58_REGEX.test(uuid58) && uuid58 <= MAX_UUID58;
|
|
351
|
+
}
|
|
204
352
|
// generate.ts
|
|
353
|
+
const random = /* @__PURE__ */ new BigUint64Array(2);
|
|
205
354
|
/**
|
|
206
355
|
* Generates a new Base58-encoded UUID (always 22 characters).
|
|
207
356
|
*
|
|
@@ -216,15 +365,9 @@ function uuid58Encode(uuid) {
|
|
|
216
365
|
* ```
|
|
217
366
|
*/
|
|
218
367
|
function uuid58() {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
let encoded = "";
|
|
224
|
-
do {
|
|
225
|
-
encoded = UUID58_ALPHABET[Number(num % UUID58_LENGTH)] + encoded;
|
|
226
|
-
num /= UUID58_LENGTH;
|
|
227
|
-
} while (num > 0n);
|
|
228
|
-
return encoded.padStart(22, UUID58_ALPHABET[0]);
|
|
368
|
+
crypto.getRandomValues(random);
|
|
369
|
+
const high = random[0] & 18446744073709490175n | 16384n;
|
|
370
|
+
const low = random[1] & 4611686018427387903n | 9223372036854775808n;
|
|
371
|
+
return encodeUint128(high << 64n | low);
|
|
229
372
|
}
|
|
230
|
-
export { UUID58_ALPHABET, UUID58_REGEX, Uuid58DecodeError, Uuid58EncodeError, isUuid58, uuid58, uuid58Decode, uuid58DecodeSafe, uuid58Encode, uuid58EncodeSafe };
|
|
373
|
+
export { UUID58_ALPHABET, UUID58_REGEX, Uuid58DecodeError, Uuid58EncodeError, isUuid58, uuid58, uuid58Decode, uuid58DecodeBytes, uuid58DecodeBytesSafe, uuid58DecodeSafe, uuid58Encode, uuid58EncodeBytes, uuid58EncodeBytesSafe, uuid58EncodeSafe };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nakanoaas/uuid58",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A tiny, zero-dependency library for generating and converting UUIDs to Base58-encoded strings.",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/nakanoasaservice/uuid58/issues"
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/nakanoasaservice/uuid58.git"
|
|
11
|
+
"url": "git+https://github.com/nakanoasaservice/uuid58.git",
|
|
12
|
+
"directory": "js"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"dist"
|
|
@@ -35,7 +36,8 @@
|
|
|
35
36
|
"build": "vp pack",
|
|
36
37
|
"check": "vp check",
|
|
37
38
|
"test": "vp test run",
|
|
38
|
-
"bench": "vp test bench --run",
|
|
39
|
+
"bench": "vp pack && vp test bench --run --reporter=default",
|
|
40
|
+
"bench:baseline": "sh bench/save-baseline.sh",
|
|
39
41
|
"jsr:dry-run": "vp pack && jsr publish --dry-run"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|