Python
hash

Hashidsを使って短いハッシュ値を生成する

概要

Hashidsというライブラリを使って短いハッシュ値を生成してみる。

ハッシュ関数には、MD5やSHA1などの有名ものがあるが、生成される桁数が多すぎて使いにくいときがある。

関数 生成桁数(16進数)
MD5 32桁
SHA1 40桁
SHA2 64桁

そういう時にHashidsを使うと簡単に短いハッシュ値を生成できる。
JavaScriptやRuby、Pythonなどの38種類の言語に対応している。(2018/5/7時点)
ただし、ハッシュ化対象は数値のみのため、文字列などは数値化してからハッシュ化する必要があるので注意。

使い方

基本

pipを使ってhashidsのライブラリをインストールする。
encodeメソッドにハッシュ化したい数値の対象を入れてあげれば、ハッシュ値が得られる。

install
pip install hashids
generate_hash.py
from hashids import Hashids

hashids = Hashids()
id = hashids.encode(123) # encode(ハッシュ化対象の数値)

print('Hash: ' + id)
output
Hash: Mj3

Saltを付与する

Saltも簡単に付与できる。Saltについては以下参照。
https://qiita.com/chroju/items/3ddae568206b8bc3d8f9

ハッシュ対象にランダムの文字列(Salt)をつけてハッシュ化することで、辞書攻撃を受けにくくすることができる。

generate_hash_with_salt.py
from hashids import Hashids

hashids = Hashids(salt='This is my salt') # saltにsalt値を指定
id = hashids.encode(123)

print('Hash: ' +  id)
output
Hash: POm

↑ Saltが付与されたことで、さっきのハッシュ値と変わった。

ハッシュ値の桁数を変更する

生成されるハッシュ値は与えたencode()に与えた桁数によって変わるみたいだが、ハッシュ対象は短くても○○桁以上のハッシュ値が欲しい、という場合は桁数の指定もできる。

generate_hash_specified_length.py
from hashids import Hashids

hashids = Hashids(hashids = Hashids(min_length=8) # min_lengthに最小桁数を指定
id = hashids.encode(123)

print('Hash: ' +  id))
output
Hash: N1aMj3bW

↑ ハッシュ値が8桁になった。

ハッシュ値の文字種を指定する

ハッシュ値として生成できる文字を指定することもできる。
最小の文字種は16種類らしい。

generate_hash_limited_chars.py
from hashids import Hashids

hashids = Hashids(
    min_length=8,  # 短すぎると分かりにくいので8文字以上にする
    alphabet='abcdefghijklmnopqrstuvwxyz' # 生成される文字を小文字ローマ字のみに指定
)
id = hashids.encode(123)
numbers = hashids.decode(id)

print('Hash: ' +  id)
output
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