SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SuperFastHash.cpp
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
16 #include "slikenet/SuperFastHash.h"
17 #include "slikenet/NativeTypes.h"
18 #include <stdlib.h>
19
20 #if !defined(_WIN32)
21 #include <stdint.h>
22 #endif
23 #include "slikenet/linux_adapter.h"
24 #include "slikenet/osx_adapter.h"
25
26 #undef get16bits
27
28 #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
29 || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
30 #define get16bits(d) (*((const uint16_t *) (d)))
31 #else
32 #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
33 +(uint32_t)(((const uint8_t *)(d))[0]) )
34 #endif
35
36 static const int INCREMENTAL_READ_BLOCK=65536;
37
38 uint32_t SuperFastHash (const char * data, int length)
39 {
40 // All this is necessary or the hash does not match SuperFastHashIncremental
41 int bytesRemaining=length;
42 unsigned int lastHash = length;
43 int offset=0;
44 while (bytesRemaining>=INCREMENTAL_READ_BLOCK)
45 {
46 lastHash=SuperFastHashIncremental (data+offset, INCREMENTAL_READ_BLOCK, lastHash );
47 bytesRemaining-=INCREMENTAL_READ_BLOCK;
48 offset+=INCREMENTAL_READ_BLOCK;
49 }
50 if (bytesRemaining>0)
51 {
52 lastHash=SuperFastHashIncremental (data+offset, bytesRemaining, lastHash );
53 }
54 return lastHash;
55
56 // return SuperFastHashIncremental(data,len,len);
57 }
58 uint32_t SuperFastHashIncremental (const char * data, int len, unsigned int lastHash )
59 {
60 uint32_t hash = (uint32_t) lastHash;
61 uint32_t tmp;
62 int rem;
63
64 if (len <= 0 || data == NULL) return 0;
65
66 rem = len & 3;
67 len >>= 2;
68
69 /* Main loop */
70 for (;len > 0; len--) {
71 hash += get16bits (data);
72 tmp = (get16bits (data+2) << 11) ^ hash;
73 hash = (hash << 16) ^ tmp;
74 data += 2*sizeof (uint16_t);
75 hash += hash >> 11;
76 }
77
78 /* Handle end cases */
79 switch (rem) {
80 case 3: hash += get16bits (data);
81 hash ^= hash << 16;
82 hash ^= data[sizeof (uint16_t)] << 18;
83 hash += hash >> 11;
84 break;
85 case 2: hash += get16bits (data);
86 hash ^= hash << 11;
87 hash += hash >> 17;
88 break;
89 case 1: hash += *data;
90 hash ^= hash << 10;
91 hash += hash >> 1;
92 }
93
94 /* Force "avalanching" of final 127 bits */
95 hash ^= hash << 3;
96 hash += hash >> 5;
97 hash ^= hash << 4;
98 hash += hash >> 17;
99 hash ^= hash << 25;
100 hash += hash >> 6;
101
102 return (uint32_t) hash;
103
104 }
105
106 uint32_t SuperFastHashFile (const char * filename)
107 {
108 FILE *fp;
109 if (fopen_s(&fp, filename, "rb")!=0)
110 return 0;
111 uint32_t hash = SuperFastHashFilePtr(fp);
112 fclose(fp);
113 return hash;
114 }
115
116 uint32_t SuperFastHashFilePtr (FILE *fp)
117 {
118 fseek(fp, 0, SEEK_END);
119 int length = ftell(fp);
120 fseek(fp, 0, SEEK_SET);
121 int bytesRemaining=length;
122 unsigned int lastHash = length;
123 char readBlock[INCREMENTAL_READ_BLOCK];
124 while (bytesRemaining>=(int) sizeof(readBlock))
125 {
126 fread(readBlock, sizeof(readBlock), 1, fp);
127 lastHash=SuperFastHashIncremental (readBlock, (int) sizeof(readBlock), lastHash );
128 bytesRemaining-=(int) sizeof(readBlock);
129 }
130 if (bytesRemaining>0)
131 {
132 fread(readBlock, bytesRemaining, 1, fp);
133 lastHash=SuperFastHashIncremental (readBlock, bytesRemaining, lastHash );
134 }
135 return lastHash;
136 }