はじめに
私はよく getHash という関数を作ってハッシュ値を生成します。
ハッシュ値は元のデータの長さによらず一定の長さとなっており、同じデータからは必ず同じハッシュ値が得られる一方、少しでも異なるデータからはまったく異なるハッシュ値が得られる。
不可逆で情報量の欠損を含む計算過程を経るため、ハッシュ値から元のデータを復元することはできない。
のでユニークな値がほしいからです。
getHash = -> cry = crypto.createHash 'SHA256' cry.update uuid.v4(), "utf8" cry.digest 'hex' |
こんな感じで。
なぜユニークな値がほしいかというと、サロゲートキーにしたりDynamoDBのIDにしてパーティションを分散化させたり、リマインダメールのトークンにしたり、非公開ページのハッシュキーにしたり、セッションを追いかけたりしたいからです。
uuid
ユニークなIDの仕様としてRFC4122というものがあります。
昔は
unixtimeを使ってたんですがうるう秒で同じ時間が2度きたり、マルチタスクで並行処理されたりすることが多くなったためこちらに変えました。
これをそのまま使ってもいいんですが、128ビットだし、記号などはいっていたり、他のキーと組み合わせたかったりしたときに扱いにくかったりいろいろと不都合なのでこれをハッシュ値にするわけです。
SHA-256
SHA-256、通称Secure Hash Algorithm 256-bitというものがあります。
ブロックチェーンで使われているわりかしメジャーな仕様です。
SHA-256はNSA(米国家安全保障局)が考案し、2001年にNIST(米国標準技術局)によって連邦情報処理標準の一つ(FIPS 180-4)として標準化された「SHA-2」規格の一部として定義されています。SHA-2では他にハッシュ値の長さが224ビットのSHA-224、384ビットのSHA-384、512ビットのSHA-512などが定義されています。
512ビット長の方が高いハッシュ強度を得られますが、SHA-512は64ビットCPU向けに最適化されたアルゴリズムであるので、32ビットCPU向けに最適化されたSHA-256とはCPUの演算系が異なります。
なるほど…。
ということで、これを生成すると
c0 8e 1e 60 19 6e a1 56 15 e4 21 33 a0 09 24 9e 7d 9b 6f 42 1a bc 72 62 4a 73 7e dd b8 c4 f9 0f |
というような文字列が得られるわけです。
16進数字の64文字で32バイトです。
これは何通りかというと16の64乗==1.157920892373162e+77とでてきます。
ゼロが77個並ぶということで1無量大数(10の68乗)よりも大きく、1Googol(10の100乗)よりも小さいという感じでしょうか・・・
おわりに
私たちの太陽系が属する銀河系には、2000億個の星があると言われています。
楽勝ですね。
ゴビ砂漠は約100万平方キロですので、深さ1メートルまでのゴビ砂漠の砂粒の数は、10の24乗粒になります。これは、「兆」の上の「京」、「京」の上の「ガイ」、さらに「ガイ」の上の「ジョ」という数の単位です。つまり、「1ジョ」粒になります。1の後ろに0(ゼロ)が24個つきます。
つまり、ゴビ砂漠の砂一粒一粒にユニークIDを割り振っても大丈夫ということになるでしょうか?
これで安心ですね!
この記事を書いた人
- 和服とvapeとСистемаと醗酵とたまごふわふわとカッティングシェイプスとジャージークラブとjuke/fwkに傾倒する人です
最近書いた記事
- 2019.10.17ES2019で追加されたあれこれを使ってみる
- 2019.09.20JavaScript で安全に扱える最大整数
- 2019.07.24Gitでハッシュ値指定が重複したらどうなるのか
- 2019.07.09ハッシュは何に使えるのか