この記事は Up&Coming という雑誌へ寄稿している内容とほぼ同一のものです。Up&Coming はフォーラムエイトさんという会社が発行している広報誌で、縁あって僕も記事を書かせていただけることとなりました。
「IT ならなんでも!」というご依頼だったのでネタチョイス的にこのブログとも相性がよく、寄稿した内容もブログに投稿することにしました。よければ本誌のほうもぜひお読みください(ネットで無料で読めます!)。
=====
あるとき突然、みなさんのクローンが生まれたとします。はたしてそのクローンはみなさんと「同じ」人でしょうか?倫理的な観点を除外したとしても、これは非常に難しい問題です。
ここで必要になるのは、なにをもって同じとするのか、または違うとするのか、そのユニークさの定義です。この一意性を与える行為は identify という言葉でよく表現されており、ID の語源(identification)そのものともいえます。
デジタル化が進んだ現代において、ID という考え方はとても身近な存在になりました。今回はそのうちいくつかの興味深い点にフォーカスし、最後は壮大なスケール感を味わえる世界へと一緒に飛び込んでいきます!
IDの例とその性質
まずはじめに、世の中にある ID の例をいくつか覗いてみましょう。
飛行機の便名
JL157 のような便名も ID の一種といえます。特徴的なのは以下の二点でしょうか。
- 航空会社の略称とナンバーが組み合わされている
- 同じ便名でも日付が違えば異なるフライトを指すことがある
JL が JAL を指すように、固有名詞の略称が ID に使われる例はよくあります。例えば空港も NRT (成田空港)のような固有の空港コードを持っていますし、株式市場におけるティッカーシンボル(MSFT: マイクロソフト)もそうです。
ふたつめの「条件が変化すれば ID としての役割を果たさなくなる」という点も非常に重要です。ID というのはあるスコープにおいて一意性が保たれていれば正しく機能しているとみなされるので、その ID がどんな範囲に対して作用しているものなのかを常に把握しておく必要があります。
ISBN(国際標準図書番号)
書籍を識別するための国際規格です。ワールドワイドで振られている番号という意味では特に目新しさはありませんが、13 桁の数値の末尾が検査数字(チェックディジット)になっている点は注目に値します。
この数値は、それ以外の 12 桁の数値によって自動的に算出される仕組みになっており、数値の打ち間違いや番号の偽造に対して効果があります。マイナンバーやクレジットカード番号でも見られる技術です。
また、12 桁の数値自体も完全にでたらめに採番されているわけではなく、国や出版社などに基づいてグループ化された階層構造によって表現がなされています。これもまた ID ではよくあるパターンで、例によってマイナンバーも同様の仕組みを持っています。
IPアドレス
IP アドレスは良くも悪くも ID についての好例といえるでしょう。当初、インターネットに接続されるすべての機器について固有の番号を振ったとしても十分に足りるだろうと考えられていましたが、現代ではこれが足りなくなってきており、「IP アドレス枯渇問題」として有名になりました。
初期は IPv4 という仕組みで、約 43 億通りの番号が存在し得ました。現在は IPv6 という新たな規格により、2^128
(2 の 128 乗)という巨大なパターン数が用意されています。
コンピューターシステムにおける ID のあり方
ID は、デジタルデータのうち最も基本的なものであるといえます。そのデータが一体何であるかを示すためにこの上なく重要な情報だからです。逆にいうと、ID がなければ特定のデータを確実に指し示すことはできません。「日本人で、男性で、東京都に住んでいて、左利きで、31 歳で…」のようにいくら絞り込んでいっても、常に「同じ条件の人がまだ他にもいるのでは?」という可能性を否定できないからです。
この話をもう少し考えてみると、ID について必要な要件というものが見えてきます。
- (想定したある範囲において)必ず重複しないようになっている
これだけです。ほかのデータに振られた ID と重複せず一意性が担保されているのなら、それは完全に ID として機能します。これがコンピューターシステムにおいてどのように実現されているのか、また少し例を覗いてみましょう。
連番
最も簡素で、しかし強力な手法です。「データを追加するたびに確実に数値を大きくしていく」というルールが守られる限り、半永久的に重複することはありません。
ただしもう少しよく考えると、以下のような課題にもすぐ気づけます。
- 順番に番号を振っていくということは、「最後に振った番号がいくつだったのか」を管理してくれる存在が必要ということになる(※1)
- ID の桁数が変わってしまうと問題があるシステムでは使えない(0 で埋めようと思うかもしれませんが、そうすると今度は想定桁数を先に決めておかないといけない難しさがあります)
とはいえ現代でも多く実利用されており、例えばサービス例として有名なのはニコニコ動画でしょうか。「ニコニコ最古の動画」といわれる古い動画の ID は「sm9」や「sm13」のようになっており、これは動画の URL からも確認できます(※2)。
ニコニコ動画のみならず、ウェブページの URL 末尾にはたいていそのデータを示すIDが付与されています。そうしないと一体どのページを表示するかの指定ができないからです。つまり URL 自体も ID といえますし、かつその本体はメインとなるデータ(今回なら動画)の ID そのものということになりますね。
タイムスタンプ
タイムスタンプ、つまり日時を表す文字列をそのまま ID にしてしまおうというアイデアです。これはある種、連番の考え方を発展させたものといえます。「常に現在時刻を使う」というルールがそのまま「前回採用された時刻より必ずあとの時刻になる」からです。
しかし、例えば秒単位で ID 化した場合、同じ秒数内で複数のデータが登録されてしまうと ID が重複します。このような問題は現代でも起きており、直近では 2023 年、とある自治体の戸籍謄本システムにおいて他人の戸籍謄本が交付されてしまうという不具合に繋がっていました(※3)。
また、タイムスタンプを簡易な数字として表現した UNIX 時刻という一般的な概念が ID として用いられたり(※4)、旧 Twitter 社が開発した Snowflake というさらに高度な ID 生成システムが存在していたりもします(※5)。
UUID
重複しない ID を簡単に発行できるシステムというのは存在しないのでしょうか。…実はあるのです。
UUID (Universally Unique Identifier) とは、いうなれば「とてつもなく膨大なパターン数からランダムに選んだあるひとつの値をひたすら出力し続ける仕組み」です。中身は非常にシンプルなのでコンピューターがあれば基本的にどこでも ID を生成できます。
UUID は例えば「fe275d49-c6ed-4adf-94d8-a8c7a895cbf5」のような形をしています。a から f までのアルファベットと数字のみで構成されていて、決められた桁数ごとにハイフンで結合されています(※6)。実はこの形式の文字列はみなさんも日ごろ数え切れないほど目にしているはずで、注文 ID、商品 ID、それらのページの URL などなど、実に多くのサービスが UUID をそのまま使用しています。最もポピュラーな ID といっても過言ではありません。
さて、ここで気になるのはやはり「本当に重複しないのか?」という点ですが、最後はこれを考察しつつ宇宙へ旅立つことにしましょう。
巨大数(グーゴロジー)の世界
UUID の文字の組み合わせはおよそ 2^128
パターンほどあり、数にしておよそ 340282366920938463463374607431768211456 通りほどです(前述した IPv6 も同じパターン数です)。UUID は先ほどのような英数字とハイフンで構成された文字列として表現するのが一般的ですが、その正体はただの巨大な数値です(128 ビットの数値だから 2^128
パターン)。この数字の大きさを感覚的に掴むための例えをいくつか見てみましょう。
よくあるのは、
- 地球上の砂粒の数(推定約
10^18
個)の約 450 京倍 - 1 秒間に 1 兆個(
10^12
)の ID を生成し続けても、全パターンを使い切るのに約 10^18 年(宇宙の年齢の約 7200 万倍の時間)かかる
などのようなものです。実に途方もない規模の数字であり、人間が一介のシステムで使う ID の重複などおよそ心配する必要がないであろうということがわかります。仮にもしどこかで重複が起きたとしても、それが同じシステムの中で発生する確率など限りなくゼロに近いものになるはずです(※7)。
UUID は単なる簡易な ID 生成システムであり、暗号学的なセキュリティは特に必要とされません。奇しくも本連載で何度も登場している「暗号学的ハッシュ関数」の代表例である SHA-256(※8)は、文字通り 256 ビット分、つまり 2^256
パターンです。これは主目的がセキュリティ方面ではあるものの、重複しない ID という観点では本稿で取り扱ってきたものと同種です(ハッシュという仕組み上、コンテンツデータが違えば必ず異なる ID として生成されることが保証されている)。
この 2^256
という数字の恐ろしさも見ていきましょう。パターン数は 115792089237316195423570985008687907853269984665640564039457584007913129639936 通りで、10^78
(つまり 78 桁の数字)です。これは観測可能な宇宙に存在すると推定される原子の数(約 10^80
個)に迫る規模で、もう何がなんだかよくわからないレベルです。
もう少し頑張って例えてみるなら、
- 太陽の寿命が来るまで今から 50 億年のあいだ、
- 100 億人の人が、
- 毎ナノ秒 1 兆個の数値を消費していく活動があり、
- その活動を、太陽系が属するこの銀河系の全ての星(~2000 億くらい)でおこなうと、
- 消費される数字の個数は、50 億年×100 億人×100000000 ナノ秒×60 秒×60 分×24 時間×365 日×1 兆個×2000 億個(星)で 59 桁の数字になる
- こんなに頑張って消費しても、50 億年後(太陽が赤色巨星になって太陽系が崩壊する頃)に消費し終わっているのは、全体の 100 京分の 1
のようになります(※9)。宇宙を感じますね…!まさに天文学的数字といえる規模です。
明確な定義はないものの、このくらいの規模以上の数値は巨大数(グーゴロジー)とよばれており、なんとあまりにも大きい数字は単位という概念すらなくなってしまいます。単位がメートルであろうが光年であろうが、その差が数字の大きさに対してあまりに意味をなさないからです。なんということでしょう、もうめまいがしてしまいますね。
「現実的に不可能だから安全です」という考え方は IT の世界ではよく見られるものですが、内側の事情を知らないとこの主張を信頼するのは難しいはず。しかし今回のように、その巨大な数字を少しでも理解しようと果敢に挑んでいくことによって、この心配がいかに杞憂であるかを実感できるのです。ID を巡る宇宙の旅、これはいろいろな意味で長く続いていきそうですね。
[注釈]:
1. 多くの場合、データを保管するためのデータベースシステムに標準で備わっている「連番採番機能」が使えますが、データが削除されたときに番号がどうなるかなど、いくつかの落とし穴も存在しており注意が必要です。
2. https://dic.nicovideo.jp/a/最古の動画
3. 本ニュースは IT 業界ではかなり話題になり、「秒単位のタイムスタンプをデータの ID として使っていたのでは」などと噂になりました。しかしニュースとして実際に報道された内容では「2 カ所のコンビニで、2 人の住民が同一タイミング(1 秒以内)で交付申請した際に、後続の処理が先行する処理を上書きしてしまう」という表現に留まっていました。参考:https://www.itmedia.co.jp/news/articles/2305/10/news114.html
4. UNIX 時刻とは、協定世界時(UTC)での1970 年 1 月 1 日午前 0 時 0 分 0 秒からの経過秒数を整数で表したものです。筆者が本稿を執筆している現在の UNIX 時刻は「1731231406」で、以降取得される UNIX 時刻は必ずこれより大きくなります。サービス例としては Slack の各メッセージリンクの URL が代表的です。
5. Snowflake では、タイムスタンプをベースとしつつ生成処理を行う各マシンの ID なども付与されています。これにより、大規模な分散システム上でも重複のない ID を高速に生成できます。注釈 3 の例でいえば、多数のコンビニで同時に処理が行われても一意性が保たれるということです。例によってこれは各ツイート(ポスト)の URL 末尾で実際に見ることができます。
6. UUID の中にも「バージョン」というそれぞれ仕組みが異なる規格が多く存在していますが、現代で UUID と表現した場合は基本的には v4 のことを指します。文中に掲載した UUID も v4 のものであり、今回はインターネット上のウェブサイトで生成しました。参考:https://www.uuidgenerator.net
7. もし同一システム内で UUID の衝突があったとしても、実はほとんどのケースで問題にはなりません。ID を採番したいシーンというのはたいていデータベース上で新たなデータを挿入するときのことになりますが、データの ID が重複した場合はそもそも挿入が成功しないようになっており、適切にリトライできる機会が与えられるのです。
8. ハッシュ関数については、Vol.2(No.143 '23 秋の号)、Vol.4(No.145 '24 春の号)をご参照ください。
9. これはある個人ブログで書かれていたものを筆者が自分の技術ブログで引用しつつ多少書式を変えたものです。引用元含むそのページを掲載しておきます:https://mirumi.tech/secret-manage-pub-repo