Last active
January 8, 2025 23:52
-
-
Save flipeador/878e735b9f6432ff7006975627104693 to your computer and use it in GitHub Desktop.
JavaScript UUIDv7 (Time-Sortable Identifier) for NodeJS and the browser.
This file contains hidden or 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
/** | |
* JavaScript UUIDv7 (Time-Sortable Identifier) for NodeJS and the browser. | |
* https://gist.github.com/flipeador/878e735b9f6432ff7006975627104693 | |
* | |
* | |
* IMPORTANT: | |
* Quickly made with the help of ChatGPT, not suitable for use in production. | |
* This implementation may not be fully compliant with the UUIDv7 specification. | |
*/ | |
const re = /^([0-9a-f]{8})-([0-9a-f]{4})-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; | |
/** | |
* Convert a byte array to an hexadecimal string. | |
*/ | |
function toHexString(a) { | |
return Array.from(a, b => b.toString(16).padStart(2, '0')).join(''); | |
} | |
/** | |
* Generate a UUIDv7 (Time-Sortable Identifier). | |
* @returns {string} | |
* The generated UUIDv7 (`00000000-0000-0000-0000-000000000000`). | |
* @example | |
* let id; console.log(id = generateId()); | |
* console.log(new Date(validateId(id)).toLocaleString()); | |
*/ | |
export function generateId() { | |
const timestamp = Date.now(); | |
// Convert the timestamp to a 6-byte hexadecimal string. | |
const timestampHex = timestamp.toString(16).padStart(12, '0'); | |
// Generate 10 random bytes for the remaining parts. | |
const randomBytes = new Uint8Array(10); | |
crypto.getRandomValues(randomBytes); | |
const randomPart1 = randomBytes.subarray(0, 2); | |
const randomPart2 = randomBytes.subarray(2, 4); | |
const randomPart3 = randomBytes.subarray(4); | |
randomPart1[0] = (randomPart1[0] & 0x0F) | 0x70; // version | |
randomPart2[0] = (randomPart2[0] & 0x3F) | 0x80; // variant | |
return [ | |
timestampHex.slice(0, 8), // first 4 bytes of timestamp | |
timestampHex.slice(8, 12), // last 2 bytes of timestamp | |
toHexString(randomPart1), // version 7 (2 bytes) | |
toHexString(randomPart2), // variant+random (2 bytes) | |
toHexString(randomPart3), // remaining 6 bytes | |
].join('-'); // 00000000-0000-0000-0000-000000000000 | |
} | |
/** | |
* Validate a UUIDv7 (Time-Sortable Identifier). | |
* @param {string} id | |
* @returns {number} | |
* The Unix timestamp encoded in the UUIDv7. | |
*/ | |
export function validateId(id) { | |
return parseInt(id.match(re).slice(1, 3).join(''), 16); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Reserved.