Swift Hashing算法使用位移来避免冲突

时间:2017-08-08 21:04:40

标签: swift algorithm hash

鉴于Person结构具有namesurname字符串属性,我想编写一个有效的散列算法,避免可互换名称和姓氏的人发生冲突(Lara Ray和Ray Lara就是例如。)。

我已经知道要摆脱Swift中的字符串连接,所以理想情况下,我正在考虑XOR 2个变量并将其中一个变换位来解决可互换问题。 这有什么不对吗?

struct Person {
    let name: String
    let surname: String

    var hashValue: Int {
        return surname.hashValue << 1 ^ name.hashValue
    }
}

1 个答案:

答案 0 :(得分:1)

Martin R在我的hash_combine旧代码评论帖中慷慨地提供了Boost here函数的Swift翻译。

我们可以在你的struct中使用这个函数:

func hash_combine(seed: inout UInt, value: UInt) {
    let tmp = value &+ 0x9e3779b9 &+ (seed << 6) &+ (seed >> 2)
    seed ^= tmp
}

struct Person {
    let name: String
    let surname: String

    var hashValue: Int {
        var seed = UInt(0)
        hash_combine(seed: &seed, value: UInt(bitPattern: name.hashValue))
        hash_combine(seed: &seed, value: UInt(bitPattern: surname.hashValue))
        return Int(bitPattern: seed)
    }
}

Person(name: "Joe", surname: "Smith").hashValue // -5143836311621647467
Person(name: "Smith", surname: "Joe").hashValue // -5146825509308597586

虽然不完美,但这应该可以减少大量样本集中的碰撞次数(请参阅带有CGPoint的示例的链接帖子。)

您可以阅读更多关于黄金比例&#34;在这里:Magic number in boost::hash_combine

我还在测试这个,但我想这可以提供更少的碰撞,而不仅仅是按位移1。