String 是否应使用Swift字符串哈希对持久数据进行索引?

String 是否应使用Swift字符串哈希对持久数据进行索引?,string,hash,swift3,String,Hash,Swift3,我在(相对)旧的代码中偶然发现了一个bug,并发现字符串哈希属性被证明不是唯一的:许多不同的字符串具有相同的哈希值 参考文档,我只找到了“一个可以用作哈希表地址的无符号整数”,它根本不提供任何信息 我的代码片段如下所示: func getCacheIndex(sUrl: String) -> Int { return sUrl.hash } 并为给定的不同字符串生成以下内容(标题参数不同,而XXXXXXX表示替换的键字符串): String有一个hashValue,但它清楚地表明,

我在(相对)旧的代码中偶然发现了一个bug,并发现字符串哈希属性被证明不是唯一的:许多不同的字符串具有相同的哈希值

参考文档,我只找到了“一个可以用作哈希表地址的无符号整数”,它根本不提供任何信息

我的代码片段如下所示:

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