連載 vol.7

IDと宇宙

みるめも(https://mirumi.me)というブログをやっている みるみ といいます。本業はソフトウェアエンジニアで、毎日プログラムかブログを書いている…という人間です。しばらくの間、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そのものということになりますね。

※1 多くの場合、データを保管するためのデータベースシステムに標準で備わっている「連番採番機能」が使えますが、データが削除されたときに番号がどうなるかなど、いくつかの落とし穴も存在しており注意が必要です。

※2 https://dic.nicovideo.jp/a/最古の動画

タイムスタンプ

タイムスタンプ、つまり日時を表す文字列をそのままIDにしてしまおうというアイデアです。これはある種、連番の考え方を発展させたものといえます。「常に現在時刻を使う」というルールがそのまま「前回採用された時刻より必ずあとの時刻になる」からです。

しかし、例えば秒単位でID化した場合、同じ秒数内で複数のデータが登録されてしまうとIDが重複します。このような問題は現代でも起きており、直近では2023年、とある自治体の戸籍謄本システムにおいて他人の戸籍謄本が交付されてしまうという不具合に繋がっていました(※3)。

また、タイムスタンプを簡易な数字として表現したUNIX時刻という一般的な概念がIDとして用いられたり(※4)、旧Twitter社が開発したSnowflakeというさらに高度なID生成システムが存在していたりもします(※5)。

※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末尾で実際に見ることができます。

UUID

重複しないIDを簡単に発行できるシステムというのは存在しないのでしょうか。…実はあるのです。

UUID (Universally Unique Identifier)とは、いうなれば「とてつもなく膨大なパターン数からランダムに選んだあるひとつの値をひたすら出力し続ける仕組み」です。中身は非常にシンプルなのでコンピューターがあれば基本的にどこでもIDを生成できます。

UUIDは例えば「fe275d49-c6ed-4adf-94d8-a8c7a895cbf5」のような形をしています。aからfまでのアルファベットと数字のみで構成されていて、決められた桁数ごとにハイフンで結合されています(※6)。実はこの形式の文字列はみなさんも日ごろ数え切れないほど目にしているはずで、注文ID、商品ID、それらのページのURLなどなど、実に多くのサービスがUUIDをそのまま使用しています。最もポピュラーなIDといっても過言ではありません。

さて、ここで気になるのはやはり「本当に重複しないのか?」という点ですが、最後はこれを考察しつつ宇宙へ旅立つことにしましょう。

※6 UUIDの中にも「バージョン」というそれぞれ仕組みが異なる規格が多く存在していますが、現代でUUIDと表現した場合は基本的にはv4のことを指します。文中に掲載したUUIDもv4のものであり、今回はインターネット上のウェブサイトで生成しました。参考:https://www.uuidgenerator.net

巨大数(グーゴロジー)の世界

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を巡る宇宙の旅、これはいろいろな意味で長く続いていきそうですね。

※7 もし同一システム内でUUIDの衝突があったとしても、実はほとんどのケースで問題にはなりません。IDを採番したいシーンというのはたいていデータベース上で新たなデータを挿入するときのことになりますが、データのIDが重複した場合はそもそも挿入が成功しないようになっており、適切にリトライできる機会が与えられるのです。

※8 ハッシュ関数については、Vol.2(No.143 '23 秋の号)Vol.4(No.145 '24 春の号)をご参照ください。

※9 これはある個人ブログで書かれていたものを筆者が自分の技術ブログで引用しつつ多少書式を変えたものです。引用元含むそのページを掲載しておきます:https://mirumi.tech/secret-manage-pub-repo

(執筆:みるみ)

(Up&Coming '25 新年号掲載)



前ページ
    
インデックス

Up&Coming

LOADING