如何将字符串散列成8位数字



无论如何,我可以哈希一个随机字符串到一个8位数没有实现任何算法自己?

可以,您可以使用内置的hashlib模块或内置的hash功能。然后,对哈希的整数形式使用模运算或字符串切片运算将最后8位数字截断:

>>> s = 'she sells sea shells by the sea shore'
>>> # Use hashlib
>>> import hashlib
>>> int(hashlib.sha1(s.encode("utf-8")).hexdigest(), 16) % (10 ** 8)
58097614L
>>> # Use hash()
>>> abs(hash(s)) % (10 ** 8)
82148974

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的方法。

只是为了完成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

从Python 3.10开始,另一种将字符串散列为8十六进制数字摘要的快速方法是使用shake.hexdigest(4):

import hashlib
h=hashlib.shake_128(b"my ascii string").hexdigest(4)
#34c0150b

注意用4而不是8,因为摘要是参数长度的两倍。

当然要注意哈希冲突

最新更新