uustupidgithubnpm

uustupid

It looks like a UUID. It can never be one.UUID の見た目。UUID には決してならない。

uustupid()

f7344a71-b58a-02ec-ed97-071a36c5b8b3

This is not a UUID. Never use it where a real UUID is expected. It is for jokes, mocks and fixtures.これは UUID ではありません。UUID が必要な場所では使わないでください。用途はジョーク、モック、テストデータです。

All 32 hex digits come from Web Crypto. The two nibbles RFC 9562 reserves are then moved out of its reach and kept there — far enough that no future revision of the spec could turn a value into a UUID after the fact.32 桁はすべて Web Crypto の乱数です。RFC 9562 が予約している 2 桁だけを範囲の外へ出し、そこに留めます — 将来 RFC が改訂されても、後から有効な UUID になってしまわない位置まで。

Out of range, and out of reach範囲の外へ、そして手の届かない場所へ

The version nibble is one of the eight RFC 9562 leaves unassigned, and the variant always has the one bit its 10xx pattern can never have. That is enough today — but 9 through f are unassigned, not unassignable. If the RFC ever gives one of them a meaning, only the variant would still be holding the line, so those versions are paired exclusively with the 0xxx variant space, which NCS backward compatibility already spent. Version 0 needs no such help: the Nil UUID owns it forever.version ニブルは RFC 9562 が割り当てていない 8 通りのいずれか、variant は 10xx が決して持てないビットを常に立てます。今日はこれで十分です — ただし 9〜f は「未割り当て」であって「割り当て不能」ではありません。将来どれかに意味が与えられたら、残るのは variant だけになる。だからそれらの version には、NCS 後方互換が既に使い切った 0xxx の variant だけを組み合わせます。version 0 にはこの手当ては不要です — Nil UUID が永久に押さえているからです。

Neither special UUID can come out, and neither needs a guard: Nil would need a zero byte where the variant bit now sits, and Max would need an f variant, which only version 0 can pair with. Everything else is untouched randomness — all 16 values show up in each of the other 30 digits.2 つの特殊な UUID はどちらも出ませんし、そのためのガードも要りません。Nil は variant のビットがある位置に 0 が必要で、Max は variant が f である必要がありますが、それと組めるのは version 0 だけだからです。それ以外は手つかずの乱数で、他の 30 桁には 16 通りすべてが出ます。

Why this is not a UUIDなぜ UUID ではないのか

Out of 36 characters, RFC 9562 assigns meaning to two. Either one may land on a value the RFC uses — but never both at once, and that is the whole trick.36 文字のうち RFC が意味を決めているのは 2 桁。どちらか片方が RFC の使う値に入ることはあります — ただし両方同時には決して入りません。仕掛けはそれだけです。

f7344a71-b58a-02ec-ed97-071a36c5b8b3

version (index 14)version(14 文字目)RFC 9562 usesRFC 9562 が使う値: 1-8  /  this valueこの値:0out of range範囲外
variant (index 19)variant(19 文字目)RFC 9562 usesRFC 9562 が使う値: 8 / 9 / a / b  /  this valueこの値:eout of range範囲外

Both out of range, at the same time, every time. That is the whole reason this is not a UUID — a validator only has to read one of them to say no.この 2 つが毎回、同時に範囲外です。UUID でない理由はそれだけ — 検証器はどちらか一方を読むだけで「違う」と言えます。

Highlighted above: the version nibble at index 14 and the variant nibble at index 19. The other 34 characters are ordinary random hex.上で色を付けているのが 14 文字目の version ニブルと 19 文字目の variant ニブルです。残り 34 文字はただの乱数の 16 進数です。

See for yourself検証してみる

Both values below were fed to an RFC 9562 validator embedded in this page. That validator shares no code with the package.このページに埋め込んだ RFC 9562 検証器に食わせた結果です。検証器はパッケージのコードを一切使っていません。

uustupid()f7344a71-b58a-02ec-ed97-071a36c5b8b3Not a UUID無効な UUID
crypto.randomUUID()9d922390-4d14-4eab-8968-c37ed85c0e11Valid UUID有効な UUID

Fresh values on every load. The verdicts never swap around.読み込むたびに新しい値で判定しています。何度試しても結果は入れ替わりません。

What the ecosystem saysエコシステムの判定

Published validators, run against a uustupid and a real UUID while this page was built. Every one of them reads the fields RFC 9562 reserves, and every one of them rejects the uustupid.公開されている検証器に uustupid と本物の UUID を食わせた結果です(このページのビルド時に実行)。いずれも RFC 9562 の予約フィールドを読むもので、すべてが uustupid を弾きます。

Validator検証器uustupid()crypto.randomUUID()
uuid.validate()Not a UUID無効な UUIDValid UUID有効な UUID
validator.isUUID()Not a UUID無効な UUIDValid UUID有効な UUID
is-uuid.anyNonNil()Not a UUID無効な UUIDValid UUID有効な UUID
zod.uuid()Not a UUID無効な UUIDValid UUID有効な UUID
yup.string().uuid()Not a UUID無効な UUIDValid UUID有効な UUID

The same table is a test in the package, so a library changing its mind fails CI. None of these libraries reach your browser — the table is computed while the page is built.この表はパッケージ側のテストにもなっているので、ライブラリの挙動が変われば CI が落ちます。これらのライブラリはブラウザには届きません — 表はビルド時に計算しています。

Generate in bulkまとめて生成

  1. 5559e6c7-4fe6-0375-fc02-51d9926d325c
  2. 52ffc60d-3400-c559-4184-bb15c2a6df29
  3. a7e171ec-42c5-c542-42d7-b7b9722fea13
  4. 051c342e-719b-fa94-4d8e-92ad70841878
  5. 65520f0c-ef2e-d783-5ece-2bc529036891
  6. 68a5bffd-45a8-b395-5a66-a8d708f44c0d
  7. 289f312e-56c2-d878-40c3-b480f9558a07
  8. 1df3a025-78fb-ec6f-75a7-b2e16a4ead0a
  9. 8a19a804-3926-ceeb-6464-da7d05955933
  10. 8bfc7d10-5c63-a9ed-7584-c0ab1447eaa8
  11. ed966107-5fa7-b181-4c59-c413621af5f4
  12. 1e7a78c6-e483-975b-467b-6102ed478c28
  13. e7b3e190-3121-bf53-782d-cd447b4a4bf9
  14. 1be9d029-ed2c-df87-4b1a-b93c89681662
  15. ac741cf4-10ff-e278-42fd-7ddcdd45f47b
  16. b1550595-c308-c626-4cf4-c466f45afb05

Installインストール

No dependencies, one entry point, under 3 kB. Runs on Node.js 22+, browsers, Cloudflare Workers, Deno and Bun.依存ゼロ、エントリ 1 本、3 kB 未満。Node.js 22+ / ブラウザ / Cloudflare Workers / Deno / Bun で動きます。

npm install uustupid

Usage使い方

import { uustupid, isUustupid } from 'uustupid'

uustupid() // => '35c8928b-2e6f-0eb0-446b-b2dd0fec9d0c'
uustupid() // => '2d3dd9e3-3048-9058-5637-710af513cf2e'

isUustupid(uustupid())          // => true
isUustupid(crypto.randomUUID()) // => false