背景
objective-c语言,NSString内的hash函数,复杂的简直逆天了。因为工作需要,这里使用python3重新实现了一遍oc内的hash算法。也许能帮到大家。
代码
# coding: UTF-8
def __hash_next_four_uri_chars(chars, result):
result = result * 67503105 + chars[0] * 16974593 + chars[1] * 66049 + chars[2] * 257 + chars[3]
return result & 0xffffffffffffffff # python不存在溢位,及时舍弃多余位
def __hash_nex_uri_char(char, result):
result = result * 257 + char
return result & 0xffffffffffffffff # 及时舍弃多余位
def __hash_ios(s):
"""
参考iOS源码https://github.com/opensource-apple/CF/blob/master/CFString.c
"""
uContents = list(map(lambda x: ord(x), s))
actualLen = len(uContents)
result = actualLen
if actualLen <= 96: # HashEverythingLimit
end4 = actualLen & (~3)
end = actualLen
pointer = 0
while pointer < end4:
result = __hash_next_four_uri_chars(uContents[pointer: pointer + 4], result)
pointer += 4
while pointer < end:
result = __hash_nex_uri_char(uContents[pointer], result)
pointer += 1
else:
for i in range(0, 8):
result = __hash_next_four_uri_chars(uContents[i * 4:i * 4 + 4], result)
con = (actualLen >> 1) - 16
for i in range(0, 8):
result = __hash_next_four_uri_chars(uContents[con + i * 4: con + i * 4 + 4], result)
con = actualLen - 32
for i in range(0, 8):
result = __hash_next_four_uri_chars(uContents[con + i * 4: con + i * 4 + 4], result)
result = result + (result << (actualLen & 31))
return result & 0xffffffffffffffff
print(__hash_ios('abc'))
print(__hash_ios('abcdef'))
print(__hash_ios(
'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'))