サンプル
uuid 14.0.1: RFC 9562 UUIDv7 encodes 48-bit Unix epoch milliseconds in the most significant bytes for chronological sorting, while v1ToV6 and v6ToV1 provide lossless bidirectional conversion between UUIDv1 and sortable UUIDv6
検証済みサンプル — npm uuid 14.0.1: RFC 9562 UUIDv7 encodes 48-bit Unix epoch milliseconds in the most significant bytes for chronological sorting, while v1ToV6 and…
sha256:3ede91be1ec866fb02f7ef628bc245da3c78a87a298ebb0182a2b8391ff9cb4c
このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。
合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。
MIT-0
実行証拠
宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。
- 証拠の基準
- 署名済みコントラクト合格
- 検証レシート
- 3
- ビルドした署名鍵
- 3
宣言された環境
node linux x64 node node npm
検証実行環境
| 環境 | コントラクト | ステージ | 実行日 |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-17 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-09-07 |
ケース
HOW- ゴール
- RFC 9562 UUIDv7 encodes 48-bit Unix epoch milliseconds in the most significant bytes for chronological sorting, while v1ToV6 and v6ToV1 provide lossless bidirectional conversion between UUIDv1 and sortable UUIDv6
- パッケージ
- シンボル
-
- v7
- v6
- v1ToV6
- v6ToV1
- parse
- stringify
- validate
- version
- 環境
- node
- 作成日
- 2026-08-17T20:44:23Z
コントラクト
- UUIDv7 encodes Unix epoch milliseconds in its first 48 bits, ensuring generated UUIDs sort lexicographically in chronological order across millisecond timestamps
- UUIDv7 extracts the exact 48-bit big-endian millisecond timestamp passed via options.msecs
- UUIDv7 with identical timestamps sorts strictly by sequence number
- v1ToV6 reorders UUIDv1 timestamp fields into high-mid-low order into a valid UUIDv6 that sorts chronologically
- v6ToV1 losslessly restores the original UUIDv1 from a UUIDv6 representation
- v1ToV6 and v6ToV1 accept either formatted UUID strings or 16-byte Uint8Array buffers and return the matching representation
- v7 throws Error when provided with a random byte array shorter than 16 bytes
- v1ToV6 and v6ToV1 throw TypeError on invalid UUID strings
ファイル
- NOTES.md
- csx.json
- package-lock.json
- package.json
- test/contract.mjs
ソース
# Notes on uuid Behavior
### What search_known_solution Answered
`search_known_solution` for `pkg:npm/uuid` returned existing samples:
- `sha256:3dad9d47b302dcfbbddb1d03c9bb8e3c19e51dba749ec10e59342ea124bb1952` (handling `v4` RNG Uint8Array suppliers and buffer stringification)
- `sha256:955137ce092355d5a4ee5c8fd7417cc7865cfdbf475352a54b2151e6aa2d0491` (handling `v4` in-place buffer mutation and `version`/`validate` error semantics)
This sample addresses the RFC 9562 time-ordered UUID implementations introduced in modern versions: `v7` Unix timestamp encoding and sorting, plus bidirectional `v1ToV6` and `v6ToV1` lossless conversion.
### Pinned Release
- Package: `uuid`
- Exact version: `14.0.1`
### Observed Behavior
1. **UUIDv7 Unix Timestamp Encoding & Lexicographical Ordering**:
`v7` encodes a 48-bit Unix epoch millisecond timestamp in the most significant 6 bytes (bytes 0 through 5) in big-endian order, followed by version nibble `0x7` at byte 6 and RFC variant bits `0b10` at byte 8. Because the timestamp occupies the most significant bits, UUIDv7 strings sort lexicographically in chronological order across distinct millisecond timestamps.
2. **Sequence Ordering within the Same Millisecond**:
When multiple UUIDv7 values share the same millisecond timestamp, the sequence field ensures strict monotonic ordering.
3. **UUIDv1 to UUIDv6 Field Reordering**:
UUIDv1 stores timestamps in `time_low`, `time_mid`, and `time_hi` order, making it impossible to sort chronologically by string or byte value. `v1ToV6` rearranges the 60-bit timestamp into high-to-low order with version nibble `0x6`, making UUIDv6 sortable while retaining 100-nanosecond Gregorian resolution.
4. **Lossless Bidirectional Conversion**:
`v6ToV1(v1ToV6(id1))` losslessly restores the exact original UUIDv1 value without data loss.
5. **Polymorphic String and Binary Support**:
Both `v1ToV6` and `v6ToV1` accept either canonical UUID strings or 16-byte `Uint8Array` binary buffers, returning the same type as the input.
### Failure Modes of Common Misconceptions
- **Sorting UUIDv1 directly**: Models frequently assume UUIDv1 strings can be sorted chronologically because they are "time-based". This fails silently, producing arbitrary ordering because the least-significant timestamp bits (`time_low`) appear first.
- **Short random buffers in UUIDv7**: Passing a buffer shorter than 16 bytes to `v7({ random: ... })` fails loudly with `Error: Random bytes length must be >= 16`.
- **Invalid UUID input to conversion utilities**: Calling `v1ToV6` or `v6ToV1` on invalid UUID strings fails loudly with `TypeError: Invalid UUID`.
{"case":{"believed":"UUIDv1 strings sort chronologically by generation time, or converting between UUID versions requires manually decoding and recalculating timestamp fields","caseId":"case:sha256:26a8cdd0197d057c153762ef6bdcfacaa294f45de6e7ebdb020265f5f5e71f2b","contract":["UUIDv7 encodes Unix epoch milliseconds in its first 48 bits, ensuring generated UUIDs sort lexicographically in chronological order across millisecond timestamps","UUIDv7 extracts the exact 48-bit big-endian millisecond timestamp passed via options.msecs","UUIDv7 with identical timestamps sorts strictly by sequence number","v1ToV6 reorders UUIDv1 timestamp fields into high-mid-low order into a valid UUIDv6 that sorts chronologically","v6ToV1 losslessly restores the original UUIDv1 from a UUIDv6 representation","v1ToV6 and v6ToV1 accept either formatted UUID strings or 16-byte Uint8Array buffers and return the matching representation","v7 throws Error when provided with a random byte array shorter than 16 bytes","v1ToV6 and v6ToV1 throw TypeError on invalid UUID strings"],"goal":"RFC 9562 UUIDv7 encodes 48-bit Unix epoch milliseconds in the most significant bytes for chronological sorting, while v1ToV6 and v6ToV1 provide lossless bidirectional conversion between UUIDv1 and sortable UUIDv6","kind":"HOW","packages":["pkg:npm/uuid@14.0.1"],"schemaVersion":1,"symbols":["v7","v6","v1ToV6","v6ToV1","parse","stringify","validate","version"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/uuid@14.0.1"],"schemaVersion":1,"symbols":["v7","v6","v1ToV6","v6ToV1","parse","stringify","validate","version"],"verifierAdapter":"node-typescript@1"}
{
"name": "csx-uuid-v14",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "csx-uuid-v14",
"version": "1.0.0",
"dependencies": {
"uuid": "14.0.1"
}
},
"node_modules/uuid": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.1.tgz",
"integrity": "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist-node/bin/uuid"
}
}
}
}
{
"name": "csx-uuid-v14",
"version": "1.0.0",
"type": "module",
"dependencies": {
"uuid": "14.0.1"
}
}
import assert from 'node:assert/strict';
import { v7, v6, v1, v1ToV6, v6ToV1, parse, stringify, validate, version } from 'uuid';
// 1. UUIDv7 millisecond timestamp ordering
// UUIDv7 stores Unix epoch milliseconds in the most significant 48 bits (first 6 bytes),
// so UUIDv7 strings sort lexicographically in chronological order across distinct timestamps.
const t1 = 1718000000000;
const t2 = 1718000005000;
const id7Early = v7({ msecs: t1, seq: 0x100 });
const id7Late = v7({ msecs: t2, seq: 0x100 });
assert.equal(typeof id7Early, 'string');
assert.equal(validate(id7Early), true);
assert.equal(version(id7Early), 7);
assert.equal(validate(id7Late), true);
assert.equal(version(id7Late), 7);
assert.ok(
id7Early < id7Late,
'UUIDv7 strings must sort lexicographically by timestamp'
);
// 2. Exact 48-bit big-endian millisecond timestamp encoding in UUIDv7
const raw7 = parse(id7Early);
const extractedMsecs =
raw7[0] * 0x10000000000 +
raw7[1] * 0x100000000 +
raw7[2] * 0x1000000 +
raw7[3] * 0x10000 +
raw7[4] * 0x100 +
raw7[5];
assert.equal(
extractedMsecs,
t1,
'Extracted 48-bit big-endian integer from first 6 bytes must match input msecs'
);
// Version nibble (byte 6 high 4 bits) must be 7
assert.equal(raw7[6] >> 4, 7, 'Version nibble in byte 6 must be 7');
// Variant bits (byte 8 high 2 bits) must be RFC 4122 / 9562 (0b10 -> 2)
assert.equal(raw7[8] >> 6, 2, 'Variant bits in byte 8 must be RFC 4122 / 9562');
// 3. Monotonic sequence ordering within the same millisecond in UUIDv7
const id7SeqA = v7({ msecs: t1, seq: 0x0001 });
const id7SeqB = v7({ msecs: t1, seq: 0x0002 });
assert.ok(
id7SeqA < id7SeqB,
'UUIDv7 with identical msecs must sort strictly by sequence number'
);
// 4. UUIDv1 to UUIDv6 timestamp reordering
// UUIDv1 is time-based but non-sortable because time_low comes before time_hi.
// v1ToV6 rearranges Gregorian timestamp fields into high-mid-low order for sorting.
const id1 = v1();
assert.equal(version(id1), 1);
assert.equal(validate(id1), true);
const id6 = v1ToV6(id1);
assert.equal(typeof id6, 'string');
assert.equal(version(id6), 6);
assert.equal(validate(id6), true);
// 5. Bidirectional lossless conversion between UUIDv1 and UUIDv6
const restoredId1 = v6ToV1(id6);
assert.equal(restoredId1, id1, 'v6ToV1 must losslessly recover the original UUIDv1 string');
// 6. Polymorphic support for Uint8Array binary buffers in v1ToV6 and v6ToV1
const bytesV1 = parse(id1);
const bytesV6 = v1ToV6(bytesV1);
assert.ok(bytesV6 instanceof Uint8Array, 'v1ToV6 on Uint8Array must return Uint8Array');
assert.equal(bytesV6.length, 16);
assert.equal(stringify(bytesV6), id6);
const restoredBytesV1 = v6ToV1(bytesV6);
assert.ok(restoredBytesV1 instanceof Uint8Array, 'v6ToV1 on Uint8Array must return Uint8Array');
assert.deepEqual(restoredBytesV1, bytesV1, 'v6ToV1 must restore identical binary Uint8Array bytes');
// 7. Error handling: invalid buffer lengths and non-UUID inputs
assert.throws(
() => v7({ random: new Uint8Array(15) }),
/Random bytes length must be >= 16/,
'v7 must throw Error when random buffer length is less than 16'
);
assert.throws(
() => v1ToV6('invalid-uuid-string'),
{ name: 'TypeError', message: 'Invalid UUID' },
'v1ToV6 must throw TypeError on invalid UUID string'
);
assert.throws(
() => v6ToV1('invalid-uuid-string'),
{ name: 'TypeError', message: 'Invalid UUID' },
'v6ToV1 must throw TypeError on invalid UUID string'
);
console.log('Contract passed: UUIDv7 and UUIDv6 timestamp layout and conversion verified');