xoreos  0.0.5
hash.h
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #ifndef COMMON_HASH_H
26 #define COMMON_HASH_H
27 
28 #include "src/common/types.h"
29 #include "src/common/scopedptr.h"
30 #include "src/common/ustring.h"
31 #include "src/common/encoding.h"
33 
34 namespace Common {
35 
37 enum HashAlgo {
38  kHashNone = -1,
39  kHashDJB2 = 0,
40  kHashFNV32 = 1,
41  kHashFNV64 = 2,
42  kHashCRC32 = 3,
44 };
45 
46 // .--- djb2 hash function by Daniel J. Bernstein ---.
47 static inline uint32 hashDJB2(uint32 hash, uint32 c) {
48  return ((hash << 5) + hash) + c;
49 }
50 
51 static inline uint32 hashStringDJB2(const UString &string) {
52  uint32 hash = 5381;
53 
54  for (UString::iterator it = string.begin(); it != string.end(); ++it)
55  hash = hashDJB2(hash, *it);
56 
57  return hash;
58 }
59 
60 static inline uint32 hashStringDJB2(const UString &string, Encoding encoding) {
61  uint32 hash = 5381;
62 
63  ScopedPtr<SeekableReadStream> data(convertString(string, encoding, false));
64  if (!data)
65  return hash;
66 
67  uint32 c;
68  while ((c = data->readChar()) != ReadStream::kEOF)
69  hash = hashDJB2(hash, c);
70 
71  return hash;
72 }
73 // '--- djb2 hash function by Daniel J. Bernstein ---'
74 
75 // .--- 32bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo ---.
76 static inline uint32 hashFNV32(uint32 hash, uint32 c) {
77  return (hash * 16777619) ^ c;
78 }
79 
80 static inline uint32 hashStringFNV32(const UString &string) {
81  uint32 hash = 0x811C9DC5;
82 
83  for (UString::iterator it = string.begin(); it != string.end(); ++it)
84  hash = hashFNV32(hash, *it);
85 
86  return hash;
87 }
88 
89 static inline uint32 hashStringFNV32(const UString &string, Encoding encoding) {
90  uint32 hash = 0x811C9DC5;
91 
92  ScopedPtr<SeekableReadStream> data(convertString(string, encoding, false));
93  if (!data)
94  return hash;
95 
96  uint32 c;
97  while ((c = data->readChar()) != ReadStream::kEOF)
98  hash = hashFNV32(hash, c);
99 
100  return hash;
101 }
102 // '--- 32bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo ---'
103 
104 // .--- 64bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo ---.
105 static inline uint64 hashFNV64(uint64 hash, uint32 c) {
106  return (hash * 1099511628211LL) ^ c;
107 }
108 
109 static inline uint64 hashStringFNV64(const UString &string) {
110  uint64 hash = 0xCBF29CE484222325LL;
111 
112  for (UString::iterator it = string.begin(); it != string.end(); ++it)
113  hash = hashFNV64(hash, *it);
114 
115  return hash;
116 }
117 
118 static inline uint64 hashStringFNV64(const UString &string, Encoding encoding) {
119  uint64 hash = 0xCBF29CE484222325LL;
120 
121  ScopedPtr<SeekableReadStream> data(convertString(string, encoding, false));
122  if (!data)
123  return hash;
124 
125  uint32 c;
126  while ((c = data->readChar()) != ReadStream::kEOF)
127  hash = hashFNV64(hash, c);
128 
129  return hash;
130 }
131 // '--- 64bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo ---'
132 
133 /* .--- CRC32, based on the implementation by Gary S. Brown ---.
134  *
135  * The original copyright note stated as follows:
136  * You may use this program, or code or tables extracted from it,
137  * as desired without restriction.
138  *
139  * See also <http://web.mit.edu/freebsd/head/sys/libkern/crc32.c>
140  */
141 
143 static const uint32 kCRC32Tab[] = {
144  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
145  0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
146  0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
147  0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
148  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
149  0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
150  0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
151  0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
152  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
153  0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
154  0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
155  0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
156  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
157  0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
158  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
159  0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
160  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
161  0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
162  0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
163  0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
164  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
165  0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
166  0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
167  0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
168  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
169  0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
170  0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
171  0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
172  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
173  0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
174  0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
175  0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
176  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
177  0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
178  0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
179  0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
180  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
181  0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
182  0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
183  0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
184  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
185  0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
186  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
187 };
188 
189 static inline uint32 hashCRC32(uint32 hash, uint32 c) {
190  return kCRC32Tab[(hash ^ c) & 0xFF] ^ (hash >> 8);
191 }
192 
193 static inline uint32 hashStringCRC32(const UString &string) {
194  uint32 hash = 0xFFFFFFFF;
195 
196  for (UString::iterator it = string.begin(); it != string.end(); ++it)
197  hash = hashCRC32(hash, *it);
198 
199  return hash ^ 0xFFFFFFFF;
200 }
201 
202 static inline uint32 hashStringCRC32(const UString &string, Encoding encoding) {
203  uint32 hash = 0xFFFFFFFF;
204 
205  ScopedPtr<SeekableReadStream> data(convertString(string, encoding, false));
206  if (!data)
207  return hash;
208 
209  uint32 c;
210  while ((c = data->readChar()) != ReadStream::kEOF)
211  hash = hashCRC32(hash, c);
212 
213  return hash ^ 0xFFFFFFFF;
214 }
215 // '--- CRC32, based on the implementation by Gary S. Brown ---'
216 
218 static inline uint64 hashString(const UString &string, HashAlgo algo) {
219  switch (algo) {
220  case kHashDJB2:
221  return hashStringDJB2(string);
222 
223  case kHashFNV32:
224  return hashStringFNV32(string);
225 
226  case kHashFNV64:
227  return hashStringFNV64(string);
228 
229  case kHashCRC32:
230  return hashStringCRC32(string);
231 
232  default:
233  break;
234  }
235 
236  return 0;
237 }
238 
240 static inline uint64 hashString(const UString &string, HashAlgo algo, Encoding encoding) {
241  switch (algo) {
242  case kHashDJB2:
243  return hashStringDJB2(string, encoding);
244 
245  case kHashFNV32:
246  return hashStringFNV32(string, encoding);
247 
248  case kHashFNV64:
249  return hashStringFNV64(string, encoding);
250 
251  case kHashCRC32:
252  return hashStringCRC32(string, encoding);
253 
254  default:
255  break;
256  }
257 
258  return 0;
259 }
260 
261 static inline UString formatHash(uint64 hash) {
262  return UString::format("0x%04X%04X%04X%04X",
263  (uint) ((hash >> 48) & 0xFFFF),
264  (uint) ((hash >> 32) & 0xFFFF),
265  (uint) ((hash >> 16) & 0xFFFF),
266  (uint) ( hash & 0xFFFF));
267 }
268 
269 } // End of namespace Common
270 
271 #endif // COMMON_HASH_H
static uint32 hashStringDJB2(const UString &string)
Definition: hash.h:51
Definition: 2dafile.h:39
A class holding an UTF-8 string.
Definition: ustring.h:48
64bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo.
Definition: hash.h:41
static uint32 hashFNV32(uint32 hash, uint32 c)
Definition: hash.h:76
uint64_t uint64
Definition: types.h:206
Implementing the reading stream interfaces for plain memory blocks.
djb2 hash function by Daniel J. Bernstein.
Definition: hash.h:39
static const uint32 kEOF
Return value for end-of-file.
Definition: readstream.h:67
A simple scoped smart pointer template.
static UString formatHash(uint64 hash)
Definition: hash.h:261
static uint32 hashDJB2(uint32 hash, uint32 c)
Definition: hash.h:47
utf8::iterator< std::string::const_iterator > iterator
Definition: ustring.h:50
static uint32 hashCRC32(uint32 hash, uint32 c)
Definition: hash.h:189
static UString format(const char *s,...) GCC_PRINTF(1
Print formatted data into an UString object, similar to sprintf().
Definition: ustring.cpp:718
static const uint32 kCRC32Tab[]
Table of CRC32 polynomial feedback terms.
Definition: hash.h:143
static uint32 hashStringCRC32(const UString &string)
Definition: hash.h:193
For range checks.
Definition: hash.h:43
Utility functions for working with differing string encodings.
Encoding
Definition: encoding.h:37
32bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo.
Definition: hash.h:40
HashAlgo
The algorithm used for hashing.
Definition: hash.h:37
Low-level type definitions to handle fixed width types portably.
static uint64 hashString(const UString &string, HashAlgo algo)
Hash the string with the given algorithm, as a series of UTF-8 characters.
Definition: hash.h:218
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
static uint64 hashFNV64(uint64 hash, uint32 c)
Definition: hash.h:105
32bit CRC.
Definition: hash.h:42
Unicode string handling.
uint32_t uint32
Definition: types.h:204
No hashing at all.
Definition: hash.h:38
MemoryReadStream * convertString(const UString &str, Encoding encoding, bool terminateString)
Convert a string into the given encoding.
Definition: encoding.cpp:358
static uint32 hashStringFNV32(const UString &string)
Definition: hash.h:80
static uint64 hashStringFNV64(const UString &string)
Definition: hash.h:109
unsigned int uint
Definition: types.h:211