仮想政府ニャルニアの歩み:1日目・マイナンバーあれ
猫はいった。マイナンバーあれ。マイナンバーがあった。
執務室にて
ここはニャルニア国の執務室である。一匹の猫が公共サービスを共通のAPIとして実装するべく動き出していた。ニャルニアは猫の国である。ニャルニアに公共サービスはない。公共サービスを新規実装するならITを使えと飼い主に教えられてきた。
彼の名はニャンマルハウト。れっきとしたニャルニア猫である。
親友であるししゃも丸と共に、公共サービスの相談をしている。
ししゃも丸「ニャンマルハウト、公共サービスっていってもどこから手を付けるんだ? 今、この国に公共サービスはない。みんな好き勝手に眠って、狩りをして、暮らしているぜ」
ニャンマルハウト「そうだな」ニャンマルハウトは小さな額に手を当てて考えた。猫の額は小さい。「まず必要なのは、どの猫がニャルニアの住人なのか、ってことだな。人間の国では国籍と呼ばれている。国籍があると、その人はその国の住人ってことになる」
ししゃも丸「国籍……難しい言葉だ。国籍がないと公共サービスは受けられないのかい?」
ニャンマルハウト「そうとも限らないからややこしいんだが……ややこしいので、この話は後回しにしよう」
猫は難しい話が嫌いである。
ニャンマルハウト「とにかく、ニャルニア国の猫には全員番号を割り振って、その番号を使って公共サービスを提供する。これをマイナンバーと呼ぼう」
ここは猫の国なのでマイナンバーですが、日本においてはマイナンバーは通称で、個人番号が正式名称のようです。
ししゃも丸「なるほど。自分の番号があれば、公共サービスを受けられるんだな。じゃあ早速、オレっちのマイナンバーを作ってくれよ。1番ってことでいいのかい?」
ししゃも丸は1番が好きだ。
ニャンマルハウト「いや、最初から順番に数字を割り振っていくと困りそうな気がするので、ここではUUIDを使おう。UUIDは128bitの数値だが、16進法を使った文字列表記が定着している。例えばこんな感じ」
ニャンマルハウトは紙に書いた。
99ee9316-3ca3-45a5-9d20-365b2336e3e8
ししゃも丸は目を回した。
ししゃも丸「こんな長い番号を覚えるのかい?」
ニャンマルハウト「やっぱ長いかな」
ししゃも丸「長いよ……。覚えるんなら、1桁くらいが限度だよ」
ニャンマルハウト「それはちょっと……。けれど、わかった。マイナンバーが長いのはある程度仕方がないけど、簡易表記や覚えなくても良い工夫を今後していくことにしよう。なにせニャルニア国は将来にわたって永久に存在するので、たくさんの桁数が必要になるんだ。誰かとマイナンバーがかぶっちゃったら、大問題だからな」
ししゃも丸「そうか。それは仕方ないな(わかってない)」
ニャンマルハウト「うむ」
マイナンバーの設計
ニャンマルハウト「UUIDを使うと言っても、人間が決めたUDIDのルールに従う必要は実際のところべつにない。128bitの数値であるという点と、表記ルールだけを踏襲した新しいものを作ろう」
ししゃも丸「8桁、4桁、4桁、4桁、12桁、ってところだな」
ニャンマルハウト「お前、12が数えられるのか」
ししゃも丸「さっき覚えたんだよ。明日には数えられない」
ニャンマルハウト「そうか……」
ニャンマルハウト「UUIDは128bitだが、これは0と1で表現する場合に128桁あるということを意味する。16進法表記では、4bitを1桁で表すから、128÷4で32桁になる。8+4+4+4+12=32、というわけだな」
こんな感じで、4bitを1桁の数値orアルファベットに変換するのである。16進法表記の時は、頭に0xを付けて10進法と区別するという習わしがある。
0101 = 2^2 + 2^0 = 4 + 1 = 5 = 0x5
1100 = 2^4 + 2^3 = 8 + 4 = 12 = 0xC
ししゃも丸「すごい、なんて計算が速いんだ! けどニャンマルハウト、お前が計算間違えをしても、俺は気づけないだろうぜ」
ニャンマルハウト「そうか……」
ニャンマルハウト「UUIDは128bitの数値だが、ルールが大きく二つある。ここではバリアント1を採用する」
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
ニャンマルハウト「このMとNは特別な意味を持つ。Mは、UUIDのバージョンを表現する。NはUUIDのバリアントを表現する」
ニャンマルハウト「16進数表記では1桁の表現力は16種類なので、UUIDには最大で16のバージョンが定義できることになる。このうちバージョン5までは、人間によって定義されている」
ニャンマルハウト「バリアントはNのうち頭の2bitもしくは3bitで表現される。Nが10xx(2)、つまり8~bなら、バリアント1だ。Nが110x(2)、つまりc~dなら、バリアント2となる。今回はバリアント1を採用するので、Nは必ず8~bとなる」
この記事では、10xx(2)は2進法表記で10から始まる4桁の数値を意味します。
UUIDバリアント1はRFC4122によって定義されています。Nの下位2bitは自由に使えます。
ニャンマルハウト「さてUUIDのどのバージョンを採用するか、ということだが……人間の定義したUUIDのバージョンはどれも一長一短で、マイナンバーとして使うにはすこし合っていないので、あたらしいバージョンを定義することにしよう。人間とかぶらないように、そうだな、バージョン12とする」
ししゃも丸「難しすぎて口を挟めなかった……。バージョン12ってことは、俺が数えられる限界の数字じゃないか」
ニャンマルハウト「じゃあやっぱバージョン13にしよう」
ししゃも丸(絶句)
ニャンマルハウト「ではまず、上位32bitは日付を表す。ニャルニア国歴1日目を1とした数値だ。32bitなので4,294,967,296日まで数えられる。だいたい11,767,033年くらい」
ししゃも丸「数が大きすぎて読み方もわかんないよ〜」
ニャンマルハウト「次の16bitは時刻を表すと言いたいところだが、桁数が足りないので、午前と午後を次のビットにもっていこう。ニャルニア国の公共サービスは24時間提供されるので、発行時刻を絞るのは難しいからな」
ししゃも丸「ブラック労働ってことか?」
ニャンマルハウト「いや……APIを使って24時間提供するので、労働者はゼロだ。クラウドサーバーは人間によって保守されるので、我々は基本的に何もしない」
ししゃも丸「やったー!」
ニャンマルハウト「話を戻そう。次の16bitのうち最初の4bitはバージョンを表すという約束なので、13……つまり、Dとなる。残りの12bitのうち、最初の1bitは時刻のうち午前と午後を表す。午前なら0、午後なら1だ。残りの11bitは特に用途がないのでゼロにしておこうかな」
ししゃも丸「そんなのでいいのか? もっと有効に使ったほうがいいんじゃ……」
ニャンマルハウト「正確には予約スペースだな。将来的に別の情報を付け足したくなったときのために用意しておくことにする」
ししゃも丸「そっか〜。ニャルニア国は滅びないから、将来のことも考えておかないといけないんだな!」
ニャンマルハウト「そうだな。そして、次の16bitのうち先頭2bitはバリアントを表すので、使えるのは14bitになる。ここはUUIDバージョン1と同じくクロックシーケンスにしよう」
ししゃも丸「クロックシーケンス?」
ニャンマルハウト「クロックシーケンスというのは、つまり連番だな。UUIDを作る度に1ずつ増やしていく数字だ。桁数がいっぱいになったら0に戻る。これで、同じ時刻にたくさんのUUIDを作っても、少なくともクロックシーケンスは違う数字になるので、重複しないことを保証できる」
ししゃも丸「ほえー。すごい賢いんだな。適当に選んだ数字だとだめなのか?」
ニャンマルハウト「誕生日のパラドックスというのがあって、適当に選んだ数字だとかぶっちゃうことがけっこうあるんだよ」
ししゃも丸「なるほど! 適当に選んだりしないんだな!」
ニャンマルハウト「最後の48桁は乱数だ」
ししゃも丸「乱数って?」
ニャンマルハウト「適当に選んだ数字だ」
ししゃも丸(腑に落ちない顔)
ニャンマルハウト「この仕様だと、1秒に2048匹の猫が新しくマイナンバーを取得し、しかもその48bit乱数がちょうどかぶった場合、マイナンバーが重複してしまうことになる。この確率はたぶんほぼゼロだ。計算してないけどな」
ニャンマルハウト「ちなみに人間の話だが、日本の出生数は一日に約3000人くらいらしい。市役所の窓口があいているのはおよそ8時間ほどだから、まあめちゃくちゃ集中したとしても、1時間で1500人の出生届に対応できれば良いだろう。1時間は3600秒だから、1秒単位で重複する可能性も十分低いと言える」
ししゃも丸「ほえー、そういう計算もしておくもんなんだな」
ニャンマルハウト「世界人口の場合、1分でおよそ150人ほどのようだな。60秒に150人なので、秒数でいえば十分重複する可能性があるだろう。ただ、これくらいならクロックシーケンスで重複排除が可能だと思う」
ししゃも丸「人間ってすごい」
ニャンマルハウト「まあ乱数の精度によっては危ないかもしれないが、そこはまた別問題だな」
ししゃも丸「いろいろあるんだな(わかってない人の感想)」
次回予告
前途多難なニャルニア国の公共サービス実装、次回はAPIの設計を行っていきます。
ニャンマルハウト「Open API って JSON-Schema と本質的に変わりがないとか、そんな話はいいんだよ」
この記事が気に入ったらサポートをしてみませんか?