在iOS版本中稳定的String的哈希值?

Ras*_*sto 12 hash hashcode nsstring ios swift

String.hashiOS的文档中,它说:

在OS X版本中,不应该依赖具有相同散列值的此属性.

(奇怪的是他们在iOS文档中谈到OS X)

好吧,我需要一个不会因iOS版本而改变的hasshing功能.它可以很简单,我不需要像SHA这样的东西.那有些图书馆吗?

有关于这一个问题在这里,但接受的(唯一的)答案有只是说,我们应该尊重在文档的说明.

War*_*ger 15

这是一个非加密哈希,对于Swift 3:

 func strHash(_ str: String) -> UInt64 {
    var result = UInt64 (5381)
    let buf = [UInt8](str.utf8)
    for b in buf {
        result = 127 * (result & 0x00ffffffffffffff) + UInt64(b)
    }
    return result
 }
Run Code Online (Sandbox Code Playgroud)

它源自C++ 11 constexpr

    constexpr uint64_t str2int(char const *input) {
    return *input                      // test for null terminator
    ? (static_cast<uint64_t>(*input) + // add char to end
       127 * ((str2int(input + 1)      // prime 127 shifts left almost 7 bits
               & 0x00ffffffffffffff))) // mask right 56 bits
    : 5381;                            // start with prime number 5381
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这两个不会产生相同的哈希值.要做到这一点,你需要在strHash中反转迭代器顺序:

for b in buf.reversed() {...}
Run Code Online (Sandbox Code Playgroud)

但是这会比我从https://useyourloaf.com/blog/swift-hashable/获得的djb2hash字符串扩展名慢13倍.

以下是一些基准测试,一百万次迭代:

hashValue execution time: 0.147760987281799
strHash execution time:   1.45974600315094
strHashReversed time:    18.7755110263824
djb2hash execution time: 16.0091370344162
sdbmhash crashed
Run Code Online (Sandbox Code Playgroud)

对于C++,str2Int大致与Swift 3的hashValue一样快:

str2int execution time: 0.136421
Run Code Online (Sandbox Code Playgroud)