String.hashValue not unique after reset app when build in Xcode 10

前端 未结 1 1218
梦如初夏
梦如初夏 2021-01-06 00:51

I have a \"get hash of string by String.hashValue\" code, that I added it below. This code worked well in Xcode 9.4.1.

Worked well means that whenever I

相关标签:
1条回答
  • 2021-01-06 01:20

    Swift 4.2 has implemented SE-0206: Hashable Enhancements. This introduces a new Hasher struct that provides a randomly seeded hash function. That's why the hashing results differ everytime (since the seed is random). You can find the implementation of the Hasher struct, with the generation of a random seed, here.

    If you want a stable hash value associated to a String, accross devices and app lauches, you could use this solution by Warren Stringer:

    let str = "Hello"
    
    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
    }
    
    strHash(str)     //177798404835661
    

    Or have these couple of extensions defined on String:

    extension String {
        var djb2hash: Int {
            let unicodeScalars = self.unicodeScalars.map { $0.value }
            return unicodeScalars.reduce(5381) {
                ($0 << 5) &+ $0 &+ Int($1)
            }
        }
    
        var sdbmhash: Int {
            let unicodeScalars = self.unicodeScalars.map { $0.value }
            return unicodeScalars.reduce(0) {
                (Int($1) &+ ($0 << 6) &+ ($0 << 16)).addingReportingOverflow(-$0).partialValue
            }
        }
    }
    
    "Hello".djb2hash    //210676686969
    "Hello".sdbmhash    //5142962386210502930
    

    (This is executed on Xcode 10, Swift 4.2)

    0 讨论(0)
提交回复
热议问题