Skip to content

Instantly share code, notes, and snippets.

@jamesperrin
Created May 21, 2025 14:27
Show Gist options
  • Save jamesperrin/37a5879005d3b4c360076380e99597c9 to your computer and use it in GitHub Desktop.
Save jamesperrin/37a5879005d3b4c360076380e99597c9 to your computer and use it in GitHub Desktop.
Generates a RFC 4122 version 4 UUID using cryptographically secure random numbers.
/**
* uuidv4.js
*
* Generates a RFC 4122 version 4 UUID using cryptographically secure random numbers.
* Falls back to Node.js crypto if not in a browser.
* Throws if no cryptographically secure PRNG is available.
*
* Vibe coding using GitHub CoPilot and ChatGPT.
*
* @returns {string} The generated UUID string in the standard 8-4-4-4-12 format.
*/
(function (global, factory) {
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
// CommonJS (Node.js)
module.exports = factory(require('crypto'));
} else if (typeof define === 'function' && define.amd) {
// AMD (if needed)
define(['crypto'], factory);
} else {
// Browser global
global.uuidv4 = factory(global.crypto);
}
})(typeof globalThis !== 'undefined' ? globalThis : this, function (cryptoSource) {
function getSecureRandomValues(arr) {
if (cryptoSource && typeof cryptoSource.getRandomValues === 'function') {
return cryptoSource.getRandomValues(arr); // Browser
} else if (cryptoSource && typeof cryptoSource.randomFillSync === 'function') {
return cryptoSource.randomFillSync(arr); // Node.js
} else {
throw new Error('No cryptographically secure random number generator available.');
}
}
function uuidv4() {
const bytes = getSecureRandomValues(new Uint8Array(16));
// Set version and variant bits
bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4
bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 10xx
const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0'));
return (
`${hex.slice(0, 4).join('')}-` +
`${hex.slice(4, 6).join('')}-` +
`${hex.slice(6, 8).join('')}-` +
`${hex.slice(8, 10).join('')}-` +
`${hex.slice(10).join('')}`
);
}
return uuidv4;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment