Skip to content

Commit

Permalink
fix: Generates invalid UUIDs
Browse files Browse the repository at this point in the history
Fixes #56
  • Loading branch information
microshine committed Feb 10, 2023
1 parent 33567ac commit 049cd7c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 7 deletions.
9 changes: 8 additions & 1 deletion src/crypto.ts
Expand Up @@ -25,11 +25,18 @@ export abstract class Crypto implements globalThis.Crypto {
* @returns UUID v4 string
*/
public randomUUID(): string {
// Generate a random Uint8Array with 16 elements
const b = this.getRandomValues(new Uint8Array(16));

// Bitwise AND operation followed by OR operator to modify 6th and 8th elements of the array
b[6] = (b[6] & 0x0f) | 0x40;
b[8] = (b[8] & 0x3f) | 0x80;

// Lowercasing the result after converting each element in hexadecimal format
const uuid = Convert.ToHex(b).toLowerCase();

return `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16)}`;
// Return the string created by extracting substrings from the given result
return `${uuid.substring(0, 8)}-${uuid.substring(8, 12)}-${uuid.substring(12, 16)}-${uuid.substring(16, 20)}-${uuid.substring(20)}`;

}
}
29 changes: 23 additions & 6 deletions test/crypto.ts
@@ -1,20 +1,37 @@
import * as assert from "assert";
import * as assert from "node:assert";
import * as nodeCrypto from "node:crypto";
import { Crypto, SubtleCrypto } from "../src";

context("Crypto", () => {

it("Crypto matches to globalThis.Crypto", () => {
class MyCrypto extends Crypto {
public subtle = new SubtleCrypto();
public getRandomValues<T extends ArrayBufferView | null>(array: T): T {
throw new Error("Method not implemented.");
class MyCrypto extends Crypto {
public subtle = new SubtleCrypto();
public getRandomValues<T extends ArrayBufferView | null>(array: T): T {
if (ArrayBuffer.isView(array)) {
const buffer = Buffer.from(array.buffer, array.byteOffset, array.byteLength);
nodeCrypto.randomFillSync(buffer);
}

return array;
}
}

it("Crypto matches to globalThis.Crypto", () => {
// tslint:disable-next-line: no-shadowed-variable
let crypto: globalThis.Crypto;
crypto = new MyCrypto();
assert.ok(crypto);
});

it("randomUUID", () => {
const crypto = new MyCrypto();

let counter = 1000;
const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
while (counter--) {
const uuid = crypto.randomUUID();
assert.ok(new RegExp(regex).test(uuid), `UUID ${uuid} is incorrect`);
}
});

});

0 comments on commit 049cd7c

Please sign in to comment.