我偶然发现了我的(相对)旧代码中的一个错误,并发现String散列属性被证明不是密集唯一的:许多不同的字符串具有相同的散列值。
参考文档,我只找到"一个无符号整数,可以用作哈希表地址"它根本没有提供任何信息。
我的代码段如下所示:
func getCacheIndex(sUrl: String) -> Int {
return sUrl.hash
}
并为给定的不同字符串生成以下内容(标题参数不同,而XXXXXXX表示替换的键字符串):
FileCache hash is -4052854053573130360 for url
https://maps.googleapis.com/maps/api/streetview?size=675x900&location=46.414382,10.013988&heading=135&pitch=-0.76&key=XXXXXXXXXXXXXXXXXXX
FileCache hash is -4052854053573130360 for url
https://maps.googleapis.com/maps/api/streetview?size=675x900&location=46.414382,10.013988&heading=180&pitch=-0.76&key=XXXXXXXXXXXXXXXXXXX
String有一个hashValue,但它清楚地表明我们不应该使用它来保持运行之间的任何东西。
你如何用Swift解决这个问题?我应该提供自己的哈希码吗?
答案 0 :(得分:2)
我暂时用我的应用程序中的自定义函数替换原生String.hash。这解决了问题,具有更好的明显分布:
public func hash(_ string: String) -> Int {
func djb(_ string: String) -> Int {
return string.utf8
.map {return $0}
.reduce(5381) {
($0 << 5) &+ $0 &+ Int($1)
}
}
return djb(string)
}
注意:只要我有时间处理分发,就可以随时替换djb哈希函数。
答案 1 :(得分:0)
快捷键4
extension String {
var persistantHash: Int {
return self.utf8.reduce(5381) {
($0 << 5) &+ $0 &+ Int($1)
}
}
}
用法示例:
"my-string".persistantHash