String 是否应使用Swift字符串哈希对持久数据进行索引?
我在(相对)旧的代码中偶然发现了一个bug,并发现字符串哈希属性被证明不是唯一的:许多不同的字符串具有相同的哈希值 参考文档,我只找到了“一个可以用作哈希表地址的无符号整数”,它根本不提供任何信息 我的代码片段如下所示:String 是否应使用Swift字符串哈希对持久数据进行索引?,string,hash,swift3,String,Hash,Swift3,我在(相对)旧的代码中偶然发现了一个bug,并发现字符串哈希属性被证明不是唯一的:许多不同的字符串具有相同的哈希值 参考文档,我只找到了“一个可以用作哈希表地址的无符号整数”,它根本不提供任何信息 我的代码片段如下所示: func getCacheIndex(sUrl: String) -> Int { return sUrl.hash } 并为给定的不同字符串生成以下内容(标题参数不同,而XXXXXXX表示替换的键字符串): String有一个hashValue,但它清楚地表明,
func getCacheIndex(sUrl: String) -> Int {
return sUrl.hash
}
并为给定的不同字符串生成以下内容(标题参数不同,而XXXXXXX表示替换的键字符串):
String有一个hashValue,但它清楚地表明,我们不应该使用它在两次运行之间保存任何内容
您将如何使用Swift解决此问题?我应该提供自己的哈希代码吗?我会在我的应用程序中用自定义func替换native 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)
}
public func散列(u-string:string)->Int{
func-djb(u-string:string)->Int{
返回字符串.utf8
.map{return$0}
.减少(5381){
($0Swift 4
extension String {
var persistantHash: Int {
return self.utf8.reduce(5381) {
($0 << 5) &+ $0 &+ Int($1)
}
}
}
是的,如果你想要稳定的散列和更大的摘要大小,你需要实现你自己的散列函数。像SHA2-256这样的东西将提供一个256位长的散列值。散列冲突(即hash(a)==hash(b),其中a!=b
)是生活中不可避免的事实。但是你想做什么呢?我正在寻找一个稳定的版本(accross multiple runs and iOS version)根据文件的URL索引文件。有什么建议吗?不需要.map{return$0}
部分。使djb函数可重放可能是准备过度了一点lol
extension String {
var persistantHash: Int {
return self.utf8.reduce(5381) {
($0 << 5) &+ $0 &+ Int($1)
}
}
}
"my-string".persistantHash