将C#的FNV64转换器移植到Python时遇到ulong乘法结果不一致问题
问题描述
尝试将C#的FNV64哈希代码移植到Python时,发现C#中ulong类型的数值相乘结果与Python整数相乘结果不一致。例如:
- C#中,
ulong a = 14695981039346656037、ulong b = 1099511628211,相乘结果为12638153115695167455 - Python中相同数值相乘结果为
16158402040730025834900042659807
需要在Python中实现与C#代码一致的FNV64哈希效果,原C#代码如下:
string path = string.Format("{0}\\{1}", locale, e); ulong basis = 14695981039346656037; ulong prime = 1099511628211; byte[] byteData = Encoding.ASCII.GetBytes(path); ulong hash = basis; foreach (byte b in byteData) { hash *= prime; hash ^= b; }
原因分析
C#的ulong是64位无符号整数,取值范围为0到2^64 - 1。当两个ulong数值相乘超出64位范围时,会自动截断高位,只保留低64位的结果。而Python的整数是任意精度的,不会自动截断,因此会保留完整的乘积值,这就是两者结果差异的根源。
Python实现方案
要在Python中得到与C#一致的结果,只需在每次乘法运算后对2^64取模,模拟ulong的截断行为。以下是对应的Python代码:
def fnv64_hash(path): basis = 14695981039346656037 prime = 1099511628211 mod = 1 << 64 # 2^64,对应ulong的最大范围上限 byte_data = path.encode('ascii') hash_val = basis for b in byte_data: hash_val = (hash_val * prime) % mod hash_val ^= b return hash_val # 示例调用(替换为你的locale和e组合的路径) # locale = "example_locale" # e = "example_file" # path = f"{locale}\\{e}" # print(fnv64_hash(path))
验证说明
用你给出的数值验证:
计算(14695981039346656037 * 1099511628211) % (1 << 64),结果为12638153115695167455,与C#的计算结果完全一致。
内容的提问来源于stack exchange,提问作者Artjom Bugajov
相关产品推荐
相关产品推荐

