Skip to content

Commit

Permalink
feat: UUID V7
Browse files Browse the repository at this point in the history
  • Loading branch information
grimly committed Mar 4, 2025
1 parent b4851b2 commit b91a79a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
15 changes: 13 additions & 2 deletions uuid.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@
max="100"
/>
</div>
<div class="col">
<label id="uuidVersionLabel" for="uuidVersion">Version</label>
<select id="uuidVersion"
name="uuidVersion"
class="form-control"
aria-labelledby="uuidVersionLabel"
>
<option value="V4" selected>UUID V4</option>
<option value="V7">UUID V7</option>
</select>
</div>
</form>
<form id="uuidForm">
<div class="mb-3">
Expand All @@ -62,7 +73,7 @@
</div>
<script type="module">
import { fromEvent, concat, of, merge, switchMap, map, tap, startWith, distinctUntilChanged } from "https://esm.sh/rxjs@7.8.1";
import { randomUUID } from "./uuid.js";
import { randomUUIDV4, randomUUIDV7 } from "./uuid.js";

const configForm = document.forms.config;
const configuration = merge(
Expand Down Expand Up @@ -93,7 +104,7 @@
switchMap(conf => concat(of(undefined), regenerate).pipe(
map(() => conf),
)),
map(({uuidCount}) => Array.from({length: uuidCount}, randomUUID).join("\n")),
map(({uuidCount, uuidVersion}) => Array.from({length: uuidCount}, uuidVersion === "V7" ? randomUUIDV7 : randomUUIDV4 ).join("\n")),
)
.subscribe(r => result.value = r);

Expand Down
32 changes: 31 additions & 1 deletion uuid.js
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
export const randomUUID = crypto.randomUUID?(()=>crypto.randomUUID()):((r,h)=>(n=>(s=>()=>'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,c=>s[c]()))({x:()=>h[n()],y:()=>h[n()%4+8]}))(()=>r.next().value))((function*(b){while(!0){for(var i of crypto.getRandomValues(b)){yield Math.trunc(i/16);yield i%16;}}})(new Uint8Array(256)),'0123456789abcdef');
function* randomNumberGenerator(buffer) {
while(true) {
for(const byte of crypto.getRandomValues(buffer)) {
yield Math.trunc(byte/16);
yield byte%16;
}
}
}

function uuidV7Timestamp() {
const unpaddedTimestamp = new Date().getTime().toString(16);
const timestamp = ('000000000000' + unpaddedTimestamp).substring(unpaddedTimestamp.length);
return `${timestamp.substring(0,8)}-${timestamp.substring(8)}`
}

const hexAlphabet = '0123456789abcdef';
const randomNumbers = randomNumberGenerator(new Uint8Array(256));
const hexDigitGenerators = {
x: () => hexAlphabet[randomNumbers.next().value],
y: () => hexAlphabet[randomNumbers.next().value % 4 + 8],
}

function withHexDigit(character) {
return hexDigitGenerators[character]();
}

export const randomUUIDV4 = crypto.randomUUID
? (()=>crypto.randomUUID())
: (()=>'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, withHexDigit))

export const randomUUIDV7 = (() => uuidV7Timestamp() + '-7xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, withHexDigit))

0 comments on commit b91a79a

Please sign in to comment.