-
-
Notifications
You must be signed in to change notification settings - Fork 145
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(random): add randomBytesFrom(), update UUID fns
- add thi.ng/hex dependency - update uuidv4Bytes() to take opt IRandom arg - refactor/optimize uuid() - add tests
- Loading branch information
1 parent
1c2f331
commit b31c872
Showing
4 changed files
with
75 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,26 @@ | ||
import { hasCrypto } from "@thi.ng/checks"; | ||
import type { IRandom } from "./api"; | ||
import { SYSTEM } from "./system"; | ||
|
||
/** | ||
* Fills given byte array with random values sourced from given {@link IRandom} | ||
* instance. | ||
* | ||
* @param rnd - | ||
* @param buf - | ||
*/ | ||
export const randomBytesFrom = (rnd: IRandom, buf: Uint8Array) => { | ||
for (let i = buf.length; --i >= 0; ) { | ||
buf[i] = rnd.int() & 0xff; | ||
} | ||
return buf; | ||
}; | ||
|
||
/** | ||
* Fills given byte array with random values. Wrapper for | ||
* `crypto.getRandomValues()` with automatic fallback to using | ||
* `Math.random` if platform doesn't provide global crypto instance. | ||
* `crypto.getRandomValues()` with automatic fallback to using `Math.random` if | ||
* platform doesn't provide global crypto instance. | ||
*/ | ||
export const randomBytes = hasCrypto() | ||
? (buf: Uint8Array) => window.crypto.getRandomValues(buf) | ||
: (buf: Uint8Array) => { | ||
const n = buf.length; | ||
for (let i = 0; i < n; i++) { | ||
buf[i] = SYSTEM.int() & 0xff; | ||
} | ||
return buf; | ||
}; | ||
: (buf: Uint8Array) => randomBytesFrom(SYSTEM, buf); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,41 @@ | ||
import { randomBytes } from "./random-bytes"; | ||
import { U16BE, U32BE, U48BE } from "@thi.ng/hex"; | ||
import type { IRandom } from "./api"; | ||
import { randomBytes, randomBytesFrom } from "./random-bytes"; | ||
|
||
/** | ||
* Uses {@link randomBytes} to fill given (optional) byte array with a UUIDv4. | ||
* Depending on if `rnd` is given, uses {@link randomBytesFrom} or | ||
* {@link randomBytes} to fill given (optional) byte array with a new UUIDv4. | ||
* Creates new Uint8Array if none given. | ||
* | ||
* @param buf - | ||
* @param rnd - | ||
*/ | ||
export const uuidv4Bytes = (buf?: Uint8Array) => { | ||
buf = randomBytes(buf || new Uint8Array(16)); | ||
export const uuidv4Bytes = (buf?: Uint8Array, rnd?: IRandom) => { | ||
buf = buf || new Uint8Array(16); | ||
buf = rnd ? randomBytesFrom(rnd, buf) : randomBytes(buf); | ||
buf[6] = 0x40 | (buf[6] & 0x0f); | ||
buf[8] = 0x80 | (buf[8] & 0x3f); | ||
return buf; | ||
}; | ||
|
||
/** | ||
* Returns a UUID string, either from given byte array, of if omitted, a new | ||
* UUID v4 produced by {@link uuidv4Bytes}. | ||
* | ||
* @param id - byte array | ||
* @param i - start index | ||
*/ | ||
export const uuid = (id?: ArrayLike<number>) => { | ||
id = id || uuidv4Bytes(); | ||
return ( | ||
U32BE(id, 0) + | ||
"-" + | ||
U16BE(id, 4) + | ||
"-" + | ||
U16BE(id, 6) + | ||
"-" + | ||
U16BE(id, 8) + | ||
"-" + | ||
U48BE(id, 10) | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import * as assert from "assert"; | ||
import { uuid, uuidv4Bytes, Xoshiro128 } from "../src"; | ||
|
||
describe("uuid", () => { | ||
it("from seeded rnd", () => { | ||
const rnd = new Xoshiro128(); | ||
let buf = uuidv4Bytes(undefined, rnd); | ||
assert.deepStrictEqual( | ||
buf, | ||
// prettier-ignore | ||
new Uint8Array([44,98,107,50,243,204,71,35,138,45,143,201,148,141,255,157]) | ||
); | ||
assert.strictEqual(uuid(buf), "2c626b32-f3cc-4723-8a2d-8fc9948dff9d"); | ||
buf = uuidv4Bytes(undefined, rnd); | ||
assert.deepStrictEqual( | ||
buf, | ||
// prettier-ignore | ||
new Uint8Array([197,193,190,153,60,45,73,45,185,35,233,127,29,138,9,147]) | ||
); | ||
assert.strictEqual(uuid(buf), "c5c1be99-3c2d-492d-b923-e97f1d8a0993"); | ||
}); | ||
}); |