web-dev-qa-db-ja.com

文字列を8桁にハッシュする方法は?

とにかく、自分でアルゴリズムを実装せずにランダムな文字列を8桁の数字にハッシュできるということはありますか?

66
dorafmon

はい、組み込みの hashlib モジュールまたは組み込みの hash 関数。次に、モジュロ演算またはハッシュの整数形式での文字列スライス演算を使用して、最後の8桁を切り落とします。

>>> s = 'she sells sea shells by the sea shore'

>>> # Use hashlib
>>> import hashlib
>>> int(hashlib.sha1(s).hexdigest(), 16) % (10 ** 8)
58097614L

>>> # Use hash()
>>> abs(hash(s)) % (10 ** 8)
82148974
108

Raymondの答えはpython2に最適です(ただし、abs()も10 ** 8前後の括弧も必要ありません)。ただし、python3には重要な注意事項があります。最初に、エンコードされた文字列を渡すことを確認する必要があります。最近では、ほとんどの場合、おそらくsha-1を避け、代わりにsha-256などを使用することをお勧めします。したがって、hashlibのアプローチは次のようになります。

>>> import hashlib
>>> s = 'your string'
>>> int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16) % 10**8
80262417

代わりにhash()関数を使用する場合、重要な注意点は、Python 2.xとは異なり、Python 3.xでは、hash()の結果がpython呼び出し間ではなく、プロセス内でのみ一貫性があります。こちらをご覧ください:

$ python -V
Python 2.7.5
$ python -c 'print(hash("foo"))'
-4177197833195190597
$ python -c 'print(hash("foo"))'
-4177197833195190597

$ python3 -V
Python 3.4.2
$ python3 -c 'print(hash("foo"))'
5790391865899772265
$ python3 -c 'print(hash("foo"))'
-8152690834165248934

これは、提案されたhash()ベースのソリューションを意味します。

hash(s) % 10**8

特定のスクリプト実行内で同じ値のみを返します。

#Python 2:
$ python2 -c 's="your string"; print(hash(s) % 10**8)'
52304543
$ python2 -c 's="your string"; print(hash(s) % 10**8)'
52304543

#Python 3:
$ python3 -c 's="your string"; print(hash(s) % 10**8)'
12954124
$ python3 -c 's="your string"; print(hash(s) % 10**8)'
32065451

そのため、アプリケーションでこれが重要かどうかによって(私の場合)、hashlibベースのアプローチに固執することになるでしょう。

55
JJC

JJCの回答を完了するために、python 3.5.3では、このようにhashlibを使用した場合の動作は正しいです:

$ python3 -c '
import hashlib
hash_object = hashlib.sha256(b"Caroline")
hex_Dig = hash_object.hexdigest()
print(hex_Dig)
'
739061d73d65dcdeb755aa28da4fea16a02b9c99b4c2735f2ebfa016f3e7fded
$ python3 -c '
import hashlib
hash_object = hashlib.sha256(b"Caroline")
hex_Dig = hash_object.hexdigest()
print(hex_Dig)
'
739061d73d65dcdeb755aa28da4fea16a02b9c99b4c2735f2ebfa016f3e7fded

$ python3 -V
Python 3.5.3
2
user8948052