2020-09-06 00:28:07 +00:00
|
|
|
// Copyright © 2020 Metabolist. All rights reserved.
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
2020-09-08 06:49:58 +00:00
|
|
|
public enum Hash: String, Codable {
|
|
|
|
case djb232
|
|
|
|
case djb2a32
|
|
|
|
case sdbm32
|
|
|
|
case fnv132
|
|
|
|
case fnv1a32
|
2020-09-06 00:28:07 +00:00
|
|
|
}
|
|
|
|
|
2020-09-08 06:49:58 +00:00
|
|
|
extension Hash {
|
2020-09-06 00:28:07 +00:00
|
|
|
func apply(_ hashable: DeterministicallyHashable) -> Int {
|
2020-09-08 06:49:58 +00:00
|
|
|
Int(Array(hashable.dataForHashingDeterministically)
|
2020-09-06 23:56:21 +00:00
|
|
|
.map(UInt32.init)
|
|
|
|
.reduce(offsetBasis, hash))
|
2020-09-06 00:28:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 02:08:30 +00:00
|
|
|
// http://www.cse.yorku.ca/~oz/hash.html
|
2020-09-06 09:18:32 +00:00
|
|
|
// http://www.isthe.com/chongo/tech/comp/fnv/
|
2020-09-06 00:28:07 +00:00
|
|
|
|
2020-09-08 06:49:58 +00:00
|
|
|
private extension Hash {
|
2020-09-06 23:56:21 +00:00
|
|
|
static let fnvPrime: UInt32 = 16777619
|
2020-09-06 09:18:32 +00:00
|
|
|
|
2020-09-06 23:56:21 +00:00
|
|
|
var offsetBasis: UInt32 {
|
2020-09-06 00:28:07 +00:00
|
|
|
switch self {
|
2020-09-08 06:49:58 +00:00
|
|
|
case .djb232, .djb2a32: return 5381
|
|
|
|
case .sdbm32: return 0
|
|
|
|
case .fnv132, .fnv1a32: return 2166136261
|
2020-09-06 00:28:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 23:56:21 +00:00
|
|
|
func hash(result: UInt32, next: UInt32) -> UInt32 {
|
2020-09-06 00:28:07 +00:00
|
|
|
switch self {
|
2020-09-08 06:49:58 +00:00
|
|
|
case .djb232:
|
2020-09-06 00:28:07 +00:00
|
|
|
return (result << 5) &+ result &+ next
|
2020-09-08 06:49:58 +00:00
|
|
|
case .djb2a32:
|
2020-09-06 23:56:21 +00:00
|
|
|
return (result << 5) &+ result ^ next
|
2020-09-08 06:49:58 +00:00
|
|
|
case .sdbm32:
|
2020-09-06 23:11:56 +00:00
|
|
|
return next &+ (result << 6) &+ (result << 16) &- result
|
2020-09-08 06:49:58 +00:00
|
|
|
case .fnv132:
|
2020-09-06 23:56:21 +00:00
|
|
|
return (result &* Self.fnvPrime) ^ next
|
2020-09-08 06:49:58 +00:00
|
|
|
case .fnv1a32:
|
2020-09-06 23:56:21 +00:00
|
|
|
return (result ^ next) &* Self.fnvPrime
|
2020-09-06 00:28:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|