Bladeren bron

fix(#48): Math.random() impl for randomId()

Sv443 9 maanden geleden
bovenliggende
commit
d7cdac004f
5 gewijzigde bestanden met toevoegingen van 65 en 48 verwijderingen
  1. 5 0
      .changeset/smooth-maps-attack.md
  2. 1 1
      README-summary.md
  3. 34 31
      README.md
  4. 0 16
      lib/math.ts
  5. 25 0
      lib/misc.ts

+ 5 - 0
.changeset/smooth-maps-attack.md

@@ -0,0 +1,5 @@
+---
+"@sv443-network/userutils": minor
+---
+
+Made `randomId()` default to using Math.random() and added the parameter `enhancedEntropy` to revert back to the much slower but also much more entropic implementation

+ 1 - 1
README-summary.md

@@ -39,7 +39,6 @@ or view the documentation of previous major releases:
     - [`clamp()`](https://github.com/Sv443-Network/UserUtils#clamp) - constrain a number between a min and max value
     - [`mapRange()`](https://github.com/Sv443-Network/UserUtils#maprange) - map a number from one range to the same spot in another range
     - [`randRange()`](https://github.com/Sv443-Network/UserUtils#randrange) - generate a random number between a min and max boundary
-    - [`randomId()`](https://github.com/Sv443-Network/UserUtils#randomid) - generate a random ID of a given length and radix
 - **Misc:**
     - [`DataStore`](https://github.com/Sv443-Network/UserUtils#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStoreSerializer`](https://github.com/Sv443-Network/UserUtils#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
@@ -51,6 +50,7 @@ or view the documentation of previous major releases:
     - [`compress()`](https://github.com/Sv443-Network/UserUtils#compress) - compress a string with Gzip or Deflate
     - [`decompress()`](https://github.com/Sv443-Network/UserUtils#decompress) - decompress a previously compressed string
     - [`computeHash()`](https://github.com/Sv443-Network/UserUtils#computehash) - compute the hash / checksum of a string or ArrayBuffer
+    - [`randomId()`](https://github.com/Sv443-Network/UserUtils#randomid) - generate a random ID of a given length and radix
 - **Arrays:**
     - [`randomItem()`](https://github.com/Sv443-Network/UserUtils#randomitem) - returns a random item from an array
     - [`randomItemIndex()`](https://github.com/Sv443-Network/UserUtils#randomitemindex) - returns a tuple of a random item and its index from an array

+ 34 - 31
README.md

@@ -41,7 +41,6 @@ View the documentation of previous major releases:
     - [`clamp()`](#clamp) - constrain a number between a min and max value
     - [`mapRange()`](#maprange) - map a number from one range to the same spot in another range
     - [`randRange()`](#randrange) - generate a random number between a min and max boundary
-    - [`randomId()`](#randomid) - generate a random ID of a given length and radix
   - [**Misc:**](#misc)
     - [`DataStore`](#datastore) - class that manages a hybrid sync & async persistent JSON database, including data migration
     - [`DataStoreSerializer`](#datastoreserializer) - class for importing & exporting data of multiple DataStore instances, including compression, checksumming and running migrations
@@ -53,6 +52,7 @@ View the documentation of previous major releases:
     - [`compress()`](#compress) - compress a string with Gzip or Deflate
     - [`decompress()`](#decompress) - decompress a previously compressed string
     - [`computeHash()`](#computehash) - compute the hash / checksum of a string or ArrayBuffer
+    - [`randomId()`](#randomid) - generate a random ID of a given length and radix
   - [**Arrays:**](#arrays)
     - [`randomItem()`](#randomitem) - returns a random item from an array
     - [`randomItemIndex()`](#randomitemindex) - returns a tuple of a random item and its index from an array
@@ -928,36 +928,6 @@ randRange(10);     // 7
 
 </details>
 
-<br>
-
-### randomId()
-Usage:  
-```ts
-randomId(length?: number, radix?: number): string
-```
-  
-Generates a cryptographically strong random ID of a given length and [radix (base).](https://en.wikipedia.org/wiki/Radix)  
-Uses the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for generating the random numbers.  
-⚠️ This is not intended for generating encryption keys, only for generating IDs with a decent amount of entropy!  
-  
-The default length is 16 and the default radix is 16 (hexadecimal).  
-You may change the radix to get digits from different numerical systems.  
-Use 2 for binary, 8 for octal, 10 for decimal, 16 for hexadecimal and 36 for alphanumeric.  
-  
-<details><summary><b>Example - click to view</b></summary>
-
-```ts
-import { randomId } from "@sv443-network/userutils";
-
-randomId();       // "1bda419a73629d4f" (length 16, radix 16)
-randomId(10);     // "f86cd354a4"       (length 10, radix 16)
-randomId(10, 2);  // "1010001101"       (length 10, radix 2)
-randomId(10, 10); // "0183428506"       (length 10, radix 10)
-randomId(10, 36); // "z46jfpa37r"       (length 10, radix 36)
-```
-
-</details>
-
 <br><br>
 
 <!-- #SECTION Misc -->
@@ -1526,6 +1496,39 @@ run();
 ```
 </details>
 
+<br>
+
+### randomId()
+Usage:  
+```ts
+randomId(length?: number, radix?: number, enhancedEntropy?: boolean): string
+```
+  
+Generates a random ID of a given length and [radix (base).](https://en.wikipedia.org/wiki/Radix)  
+  
+The default length is 16 and the default radix is 16 (hexadecimal).  
+You may change the radix to get digits from different numerical systems.  
+Use 2 for binary, 8 for octal, 10 for decimal, 16 for hexadecimal and 36 for alphanumeric.  
+  
+If `enhancedEntropy` is set to true (false by default), the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) is used for generating the random numbers.  
+Note that this takes MUCH longer, but the generated IDs will have a higher entropy.  
+  
+⚠️ Not suitable for generating anything related to cryptography! Use [SubtleCrypto's `generateKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey) for that instead.  
+  
+<details><summary><b>Example - click to view</b></summary>
+
+```ts
+import { randomId } from "@sv443-network/userutils";
+
+randomId();       // "1bda419a73629d4f" (length 16, radix 16)
+randomId(10);     // "f86cd354a4"       (length 10, radix 16)
+randomId(10, 2);  // "1010001101"       (length 10, radix 2)
+randomId(10, 10); // "0183428506"       (length 10, radix 10)
+randomId(10, 36); // "z46jfpa37r"       (length 10, radix 36)
+```
+
+</details>
+
 <br><br>
 
 <!-- #SECTION Arrays -->

+ 0 - 16
lib/math.ts

@@ -44,19 +44,3 @@ export function randRange(...args: number[]): number {
 
   return Math.floor(Math.random() * (max - min + 1)) + min;
 }
-
-/**
- * Generates a random ID with the specified length and radix (16 characters and hexadecimal by default)  
- * Uses [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for better cryptographic randomness  
- * ⚠️ Not suitable for generating encryption keys! Use [`crypto.subtle.generateKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey) for that.
- * @param length The length of the ID to generate (defaults to 16)
- * @param radix The [radix](https://en.wikipedia.org/wiki/Radix) of each digit (defaults to 16 which is hexadecimal. Use 2 for binary, 10 for decimal, 36 for alphanumeric, etc.)
- */
-export function randomId(length = 16, radix = 16): string {
-  const arr = new Uint8Array(length);
-  crypto.getRandomValues(arr);
-  return Array.from(
-    arr,
-    (v) => mapRange(v, 0, 255, 0, radix).toString(radix).substring(0, 1),
-  ).join("");
-}

+ 25 - 0
lib/misc.ts

@@ -1,4 +1,5 @@
 import { getUnsafeWindow } from "./dom.js";
+import { mapRange } from "./math.js";
 import type { Stringifiable } from "./types.js";
 
 /**
@@ -158,3 +159,27 @@ export async function computeHash(input: string | ArrayBuffer, algorithm = "SHA-
 
   return hashHex;
 }
+
+/**
+ * Generates a random ID with the specified length and radix (16 characters and hexadecimal by default)  
+ *   
+ * ⚠️ Not suitable for generating anything related to cryptography! Use [SubtleCrypto's `generateKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey) for that instead.
+ * @param length The length of the ID to generate (defaults to 16)
+ * @param radix The [radix](https://en.wikipedia.org/wiki/Radix) of each digit (defaults to 16 which is hexadecimal. Use 2 for binary, 10 for decimal, 36 for alphanumeric, etc.)
+ * @param enhancedEntropy If set to true, uses [`crypto.getRandomValues()`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) for better cryptographic randomness (this also makes it take MUCH longer to generate)  
+ */
+export function randomId(length = 16, radix = 16, enhancedEntropy = false): string {
+  if(enhancedEntropy) {
+    const arr = new Uint8Array(length);
+    crypto.getRandomValues(arr);
+    return Array.from(
+      arr,
+      (v) => mapRange(v, 0, 255, 0, radix).toString(radix).substring(0, 1),
+    ).join("");
+  }
+
+  return Array.from(
+    { length },
+    () => Math.floor(Math.random() * radix).toString(radix),
+  ).join("");
+}