-
Notifications
You must be signed in to change notification settings - Fork 0
/
FNVHash.swift
86 lines (67 loc) · 2.24 KB
/
FNVHash.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//
// FNVHash.swift
//
// A Swift implementation of the Fowler–Noll–Vo (FNV) hash function
// See http://www.isthe.com/chongo/tech/comp/fnv/
//
// Created by Mauricio Santos on 3/9/15.
import Foundation
// MARK:- Constants
private struct Constants {
// FNV parameters
#if arch(arm64) || arch(x86_64) // 64-bit
static let OffsetBasis: UInt = 14695981039346656037
static let FNVPrime: UInt = 1099511628211
#else // 32-bit
static let OffsetBasis: UInt = 2166136261
static let FNVPrime: UInt = 16777619
#endif
}
// MARK:- Public API
/// Calculates FNV-1 hash from a raw byte sequence, such as an array.
func fnv1<S:SequenceType where S.Generator.Element == UInt8>(bytes: S) -> UInt {
var hash = Constants.OffsetBasis
for byte in bytes {
hash = hash &* Constants.FNVPrime // &* means multiply with overflow
hash ^= UInt(byte)
}
return hash
}
/// Calculates FNV-1a hash from a raw byte sequence, such as an array.
func fnv1a<S:SequenceType where S.Generator.Element == UInt8>(bytes: S) -> UInt {
var hash = Constants.OffsetBasis
for byte in bytes {
hash ^= UInt(byte)
hash = hash &* Constants.FNVPrime
}
return hash
}
/// Calculates FNV-1 hash from a String using it's UTF8 representation.
func fnv1(str: String) -> UInt {
return fnv1(str.utf8)
}
/// Calculates FNV-1a hash from a String using it's UTF8 representation.
func fnv1a(str: String) -> UInt {
return fnv1a(str.utf8)
}
/// Calculates FNV-1 hash from an integer type.
func fnv1<T: IntegerType>(value: T) -> UInt {
return fnv1(bytesFromNumber(value))
}
/// Calculates FNV-1a hash from an integer type.
func fnv1a<T: IntegerType>(value: T) -> UInt {
return fnv1a(bytesFromNumber(value))
}
/// Calculates FNV-1 hash from a floating point type.
func fnv1<T: FloatingPointType>(value: T) -> UInt {
return fnv1(bytesFromNumber(value))
}
/// Calculates FNV-1a hash from a floating point type.
func fnv1a<T: FloatingPointType>(value: T) -> UInt {
return fnv1a(bytesFromNumber(value))
}
private func bytesFromNumber<T>(var value: T) -> [UInt8] {
return withUnsafePointer(&value) {
Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>($0), count: sizeof(T)))
}
}