将输入转换为0到255范围内整数的哈希函数?

10

我需要一个非常简单的Python哈希函数,它将把一个字符串转换为0到255之间的整数。

例如:

>>> hash_function("abc_123")
32
>>> hash_function("any-string-value")
99

无论整数是什么,只要每次调用函数时都得到相同的整数即可。
我想使用这个整数根据网络名称生成随机子网掩码。

你打算如何获取哈希值? - vishes_shell
你的使用情况可以仅区分256个唯一值,并且超出该范围的任何内容都会发生冲突吗?使用更大的标准哈希有什么问题? - deceze
1
我想将输出用作网络子网掩码的一部分。 - Mikhail Janowski
1个回答

27

你可以直接使用 hash() 函数的模数

def onebyte_hash(s):
    return hash(s) % 256

这是字典和集合使用的方法(哈希取模内部表的大小)。

演示:

>>> onebyte_hash('abc_123')
182
>>> onebyte_hash('any-string-value')
12
注意:在 Python 3.3 及以上版本中,默认启用了哈希随机化,导致在重新启动 Python 进程时会得到不同的值。只有在不重启 Python 进程或将 PYTHONHASHSEED 设置为一个固定的十进制数(使用0完全禁用)时,哈希才是稳定的。在 Python 2 和 3.0 到 3.2 中,哈希随机化要么不可用,要么需要显式设置种子才能启用。
另一种选择是仅使用hashlib.md5(),并且只取(整数值的)第一个字节。
import hashlib

try:
    # Python 2; Python 3 will throw an exception here as bytes are required
    hashlib.md5('')
    def onebyte_hash(s):
        return ord(hashlib.md5(s).digest()[0])
except TypeError:
    # Python 3; encode the string first, return first byte
    def onebyte_hash(s):
        return hashlib.md5(s.encode('utf8')).digest()[0]

MD5是一种被广泛应用的加密哈希算法,其输出结果稳定,并且不受哈希随机化的影响,适用于所有版本的Python。

后者的缺点是它会稍微慢一些;Python会在字符串对象上缓存字符串哈希值,因此大部分情况下获取哈希值都很快捷和廉价。


1
我正在使用Python 3.6,每次运行以下程序时都会得到随机哈希值。我做错了什么? import os os.environ["PYTHONHASHSEED"] = "8675309" print(hash('This string')) - All The Rage
1
@AlltheRage:你需要在启动Python之前,在父环境中设置种子。 - Martijn Pieters
1
你可以扩展这种方法以获取任何范围,例如 int(hashlib.md5(s.encode('utf8')).hexdigest(),16) % 10000 给出0-9999的哈希值。也许这不是最优的,但这是我用的。 - Jean-François Fabre
@Jean-FrançoisFabre:那为什么不直接从更多的摘要字节中加载整数,而不是来回转换十六进制摘要? - Martijn Pieters
是的,那也可以运行,但模运算仍适用于不是2的幂值。 - Jean-François Fabre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接