0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UUID v4 は「ほぼ絶対に被らない」はずだったのに?──Hacker Newsで話題になった“実際の衝突”騒動を読む

0
Posted at
  • Hacker Newsで「UUID v4 が実際に衝突した」という投稿が話題になった
  • UUID v4 はランダム生成に近い仕組みだが、前提は「ちゃんとした entropy(乱雑さの元)」があること
  • もし entropy が壊れていたり足りなかったりすると、理論上ありえないはずの重複が起きうる
  • コメント欄では、Cloudflare の lava lamp wall のような entropy 集めの話まで広がった
  • 「ランダムIDだから安心」はちょっと危ない、という教訓がかなり強い

何が起きたのか

元記事は、Hacker News の Ask HN 投稿です。
投稿者は「今朝、データベースが重複 UUID を検出した」と書き込みました。

しかも、ただの重複っぽいミスではありません。

  • 既存レコードは 2025年に追加されたもの
  • 今日、新しい文書を insert したら
  • UUID v4 がまったく同じ値になった

投稿者は使っていたコードもシンプルだと説明しています。

import { v4 as uuidv4 } from "uuid";
const document_id = uuidv4();

つまり、「ライブラリに任せてUUIDを発行して、そのままDBに入れているだけ」。
それで衝突した、という話です。

しかもデータベース全体のレコード数は 約1万5000件
普通に考えると、UUID v4 の衝突なんて天文学的に起きにくいはずです。
だから投稿者も「どう考えてもおかしい」と困惑していました。

個人的にも、これはかなり面白い話だと思います。
というのも、UUIDって「衝突しないための便利ID」の代表格みたいに扱われがちだからです。
それが実際にぶつかったとなると、「え、そんなことあるの?」となるのは自然です。

UUID v4 ってそもそも何?

UUID は Universally Unique Identifier の略で、ざっくり言うと「世界で重複しにくいID」です。
その中でも v4 は、内容のほとんどをランダムに決める方式です。

よくあるイメージとしては、

  • 連番のIDだと予測されやすい
  • UUIDなら予測しにくいし、重複もほぼ起きない

という感じです。

ただし、ここで大事なのは “ランダムに見える” ことと “本当に十分ランダム” であることは別 だという点です。
UUID v4 は、ちゃんとした乱数源(entropy source)に支えられて初めて「衝突しにくい」わけです。

コメント欄の核心: 問題は UUID そのものより entropy

最上位のコメントで、あるユーザーはかなり本質的なことを言っています。

UUIDv4 の安全性は、高品質な entropy source があることを前提にしている。
その前提は、ハードウェア不良やソフトウェアバグ、entropy の意味を理解していない開発者によって壊れることがある。

要するに、UUID v4 が悪いというより、UUID を作る元の“乱雑さ”が壊れていると事故る、という話です。

ここ、地味ですが超重要です。
ランダムIDは「理論上ほぼ被らない」のであって、「宇宙の法則として絶対に被らない」わけではありません。
もし乱数生成器が変な状態なら、同じIDを何度も出してしまうことはありえます。

しかも entropy が壊れているかどうかは、意外と検出が難しい。
だから多くのシステムは、その異常に気づけないまま使い続け、衝突が起きて初めて発覚する
これはかなり嫌な現実です。かなり人間くさい失敗でもあります。

なぜ Cloudflare の lava lamp wall の話になるのか

コメント欄では、Cloudflare がオフィスに置いている lava lamp wall の話も出てきました。
あの、ゆらゆら動くランプの壁です。

これは見た目が面白いだけではなく、entropy の源の一つとして有名です。
Cloudflare は他にも、pendulum(振り子)や mobile など、いろいろな物理現象を使って乱雑さを集めているそうです。

ここでのポイントは、物理世界はコンピュータよりランダムっぽいということです。
ソフトウェアだけで完璧なランダムを作るのは難しいので、

  • カメラのノイズ
  • マウスの動き
  • ボタン入力のタイミング
  • 温度雑音
  • 放射線

みたいな「予測しづらい現象」を混ぜることで、乱数の質を上げるわけです。

私はこの話、すごく好きです。
コンピュータの世界って基本的に「再現性」が命ですが、乱数だけは逆に「再現できないこと」が命なんですよね。
そのギャップがいかにも面白い。

Von Neumann の方法の話も盛り上がった

image_0001.svg

コメント欄では、少し数学っぽい話として Von Neumann method も話題になりました。
これは、偏ったコイン(表が出やすいコイン)から、偏りのない結果を取り出す方法です。

やり方はシンプルで、

  • 2回コインを投げる
  • HTTH なら採用
  • HHTT は捨てる

というものです。

なぜこれで公平になるのかというと、HTTH は起こる確率が同じだからです。
コインが表寄りでも裏寄りでも、順番の入れ替わりは対称なので、採用したときだけ見れば 50/50 になる、という理屈です。

このあたりのコメントは、技術の話なのに妙に楽しいです。
「乱数って、こんなふうに“偏りを消す”ことができるのか」と気づかされます。
数学の力って、こういうところで気持ちよく効くんですよね。

でも「たくさん entropy を混ぜれば安心」でもない

コメントの流れでは、「entropy の源は多ければ多いほどいい」という意見もありました。
ただ、これは半分正しくて半分危ういと思います。

たしかに、複数の独立した entropy を混ぜるのは有効です。
でも大事なのは数ではなく、独立性と品質です。

  • 似たような入力ばかり集めても意味が薄い
  • 混ぜ方が雑だと、強い偏りが残る
  • 1つでも重要な入力が破綻していると、全体の品質が落ちる

つまり、「100個集めたから勝ち」ではないんですよね。
むしろ、ちゃんと質の違う入力を、ちゃんと混ぜることが大事だと思います。

この話の本当に怖いところ

この投稿が面白いのは、単なる珍事ではなく、実務的な怖さがあるからです。

UUID v4 は多くのシステムで「ほぼ安心して使える」便利な仕組みです。
でも、今回のように実際に衝突が起きたなら、考えるべきは「UUIDは信頼できない!」ではなく、

  • 乱数の生成環境は正常だったか
  • 実行環境に偏りはなかったか
  • コンテナやVMの起動直後に entropy が足りない状態ではなかったか
  • ライブラリやOSの乱数生成に問題はなかったか

といった、周辺の土台です。

ここが重要です。
IDの方式そのものより、IDを作る基盤の健全性のほうが本質的なリスクになりうる。
これは、実装の細部よりインフラや環境のほうが怖い、という現場あるあるでもあります。

個人的な感想

個人的には、この話は「UUID v4 が壊れた」というより、“ランダム” を信用しすぎると痛い目を見るという教訓だと感じました。

人は「UUIDはほぼ一意」という言葉を聞くと、つい「まあ大丈夫でしょ」と思ってしまいます。
でも実際には、そこには

  • ハードウェア
  • OS
  • ライブラリ
  • 実行環境
  • 実装ミス

みたいな、無数の前提が挟まっているんですよね。

技術って、便利になるほどブラックボックス化しがちです。
だからこそ、こういう「ありえないはずの事故」は、むしろありがたい警鐘なのかもしれません。

まとめると

このHacker Newsの投稿は、単なる珍事件ではなく、
UUID v4 の信頼性は“十分な entropy があること”を前提にしている、という基本を思い出させる話でした。

「重複しないはずのIDが重複した」とき、疑うべきはUUIDの数学だけではありません。
その背後にある乱数生成の品質、環境、実装全体です。

そして何より、コンピュータの世界で「ランダム」は思っているよりずっと繊細だ、ということ。
そこがこの話のいちばん面白くて、いちばん怖いところだと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?