概要
Hashidsというライブラリを使って短いハッシュ値を生成してみる。
ハッシュ関数には、MD5やSHA1などの有名ものがあるが、生成される桁数が多すぎて使いにくいときがある。
関数 | 生成桁数(16進数) |
---|---|
MD5 | 32桁 |
SHA1 | 40桁 |
SHA2 | 64桁 |
そういう時にHashidsを使うと簡単に短いハッシュ値を生成できる。
JavaScriptやRuby、Pythonなどの38種類の言語に対応している。(2018/5/7時点)
ただし、ハッシュ化対象は数値のみのため、文字列などは数値化してからハッシュ化する必要があるので注意。
使い方
基本
pipを使ってhashidsのライブラリをインストールする。
encodeメソッドにハッシュ化したい数値の対象を入れてあげれば、ハッシュ値が得られる。
pip install hashids
from hashids import Hashids
hashids = Hashids()
id = hashids.encode(123) # encode(ハッシュ化対象の数値)
print('Hash: ' + id)
Hash: Mj3
Saltを付与する
Saltも簡単に付与できる。Saltについては以下参照。
https://qiita.com/chroju/items/3ddae568206b8bc3d8f9
ハッシュ対象にランダムの文字列(Salt)をつけてハッシュ化することで、辞書攻撃を受けにくくすることができる。
from hashids import Hashids
hashids = Hashids(salt='This is my salt') # saltにsalt値を指定
id = hashids.encode(123)
print('Hash: ' + id)
Hash: POm
↑ Saltが付与されたことで、さっきのハッシュ値と変わった。
ハッシュ値の桁数を変更する
生成されるハッシュ値は与えたencode()に与えた桁数によって変わるみたいだが、ハッシュ対象は短くても○○桁以上のハッシュ値が欲しい、という場合は桁数の指定もできる。
from hashids import Hashids
hashids = Hashids(hashids = Hashids(min_length=8) # min_lengthに最小桁数を指定
id = hashids.encode(123)
print('Hash: ' + id))
Hash: N1aMj3bW
↑ ハッシュ値が8桁になった。
ハッシュ値の文字種を指定する
ハッシュ値として生成できる文字を指定することもできる。
最小の文字種は16種類らしい。
from hashids import Hashids
hashids = Hashids(
min_length=8, # 短すぎると分かりにくいので8文字以上にする
alphabet='abcdefghijklmnopqrstuvwxyz' # 生成される文字を小文字ローマ字のみに指定
)
id = hashids.encode(123)
numbers = hashids.decode(id)
print('Hash: ' + id)
Hash: vpamrybl
↑ 小文字のローマ字のみになった。
衝突しないのか
ハッシュ値が短くなれば、生成できるハッシュ値の数も減るので衝突するのでは?と疑問思い調べて見たところ、公式に書いてあった。
There are no collisions because the method is based on integer to hex conversion. As long as you don't change constructor arguments midway, the generated output will stay unique to your salt.
整数を16進数に変換しているから衝突はないらしい。なぜそうなのかはよく分からない...
まとめ
ハッシュ化できるのは数値のみだが、さくっと短か目のハッシュ値が欲しいときはhashidsで簡単にできる。
参考
https://hashids.org/
https://github.com/davidaurelio/hashids-python