我正在尝试编写一个哈希函数,将 64 位整数转换为较短的字符串,反之亦然:我希望它是完全可逆的,没有冲突。
我的想法是这样一个int的最大值是
18,446,744,073,709,551,615
(20位数字,以10为底)。如果我将其转换为 base 64(基数;不是常用的编码方案!),那么我可以用 13 个字符表示相同的值(64 ^ 13 = 302,231,454,903,657,293,676,544
)。
我编写了以下函数来将 radix10 int 转换为 radix64 字符串,但我不能 100% 确定我没有错过边缘情况:
const HASH : Array # Contains 64 characters: 0-9, a-z, A-Z, '?', and '!'
const HIGH_MASK : int = int(pow(2, 64)) # 0b10000000...
func to_hash(value : int) -> String:
var string : String = ""
while true:
string = HASH[value & HASH_MASK] + string
# Shift bits without preserving high bit.
for _i in range(6): # 2 ^ 6 = 64, the number of hash characters available.
value = (value >> 1) & (~HIGH_MASK)
if value == 0:
break
return string
func from_hash(string : String) -> int:
var value : int = 0
for character in string:
var bits : int = HASH.find(character)
assert(bits != -1, "Invalid hash character: " + character)
value = (value << 6) | bits
return value
那个算法有碰撞吗?或者它会满足我的用例,即每个唯一的 int64 都会产生一个唯一的、唯一可逆的哈希字符串吗?