forked from TheAlgorithms/Java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFNV1aHash.java
More file actions
140 lines (124 loc) · 4.54 KB
/
FNV1aHash.java
File metadata and controls
140 lines (124 loc) · 4.54 KB
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.thealgorithms.others;
/**
* FNV-1a (Fowler-Noll-Vo) is a non-cryptographic hash function created by Glenn Fowler, Landon
* Curt Noll, and Kiem-Phong Vo.
*
* <p>The FNV-1a variant provides better avalanche characteristics (bit changes distribute more
* uniformly) compared to the original FNV-1.
*
* <p>Key properties:
* <ul>
* <li>Fast computation - simple operations (XOR and multiply)</li>
* <li>Good distribution - minimizes hash collisions</li>
* <li>Non-cryptographic - not suitable for security purposes</li>
* <li>Widely used in hash tables, checksums, and data structures</li>
* </ul>
*
* <p>Algorithm: hash = FNV_offset_basis for each byte in data: hash = hash XOR byte hash = hash *
* FNV_prime
*
* <p>FNV-1a 32-bit: FNV_offset_basis = 2166136261 (0x811c9dc5) FNV_prime = 16777619 (0x01000193)
*
* <p>FNV-1a 64-bit: FNV_offset_basis = 14695981039346656037 (0xcbf29ce484222325) FNV_prime =
* 1099511628211 (0x100000001b3)
*
* <p>Time Complexity: O(n) where n is the length of the input
* <p>Space Complexity: O(1)
*
* @author dinilH
* @see <a href="http://www.isthe.com/chongo/tech/comp/fnv/">FNV Hash</a>
* @see <a href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV on Wikipedia</a>
*/
public final class FNV1aHash {
// FNV-1a 32-bit parameters
private static final int FNV_32_INIT = 0x811c9dc5;
private static final int FNV_32_PRIME = 0x01000193;
// FNV-1a 64-bit parameters
private static final long FNV_64_INIT = 0xcbf29ce484222325L;
private static final long FNV_64_PRIME = 0x100000001b3L;
private FNV1aHash() {
// Utility class - prevent instantiation
}
/**
* Computes the 32-bit FNV-1a hash of the input string.
*
* @param data the input string to hash
* @return the 32-bit hash value as an integer
* @throws IllegalArgumentException if data is null
*/
public static int hash32(String data) {
if (data == null) {
throw new IllegalArgumentException("Input string cannot be null");
}
return hash32(data.getBytes(java.nio.charset.StandardCharsets.UTF_8));
}
/**
* Computes the 32-bit FNV-1a hash of the input byte array.
*
* @param data the input byte array to hash
* @return the 32-bit hash value as an integer
* @throws IllegalArgumentException if data is null
*/
public static int hash32(byte[] data) {
if (data == null) {
throw new IllegalArgumentException("Input byte array cannot be null");
}
int hash = FNV_32_INIT;
for (byte b : data) {
hash ^= (b & 0xff); // XOR with byte (ensure unsigned)
hash *= FNV_32_PRIME; // Multiply by FNV prime
}
return hash;
}
/**
* Computes the 64-bit FNV-1a hash of the input string.
*
* @param data the input string to hash
* @return the 64-bit hash value as a long
* @throws IllegalArgumentException if data is null
*/
public static long hash64(String data) {
if (data == null) {
throw new IllegalArgumentException("Input string cannot be null");
}
return hash64(data.getBytes(java.nio.charset.StandardCharsets.UTF_8));
}
/**
* Computes the 64-bit FNV-1a hash of the input byte array.
*
* @param data the input byte array to hash
* @return the 64-bit hash value as a long
* @throws IllegalArgumentException if data is null
*/
public static long hash64(byte[] data) {
if (data == null) {
throw new IllegalArgumentException("Input byte array cannot be null");
}
long hash = FNV_64_INIT;
for (byte b : data) {
hash ^= (b & 0xff); // XOR with byte (ensure unsigned)
hash *= FNV_64_PRIME; // Multiply by FNV prime
}
return hash;
}
/**
* Computes the 32-bit FNV-1a hash and returns it as a hex string.
*
* @param data the input string to hash
* @return the hash value as an 8-character hex string
* @throws IllegalArgumentException if data is null
*/
public static String hash32Hex(String data) {
return String.format("%08x", hash32(data));
}
/**
* Computes the 64-bit FNV-1a hash and returns it as a hex string.
*
* @param data the input string to hash
* @return the hash value as a 16-character hex string
* @throws IllegalArgumentException if data is null
*/
public static String hash64Hex(String data) {
return String.format("%016x", hash64(data));
}
}