1 |
root |
1.1 |
#include "EXTERN.h" |
2 |
|
|
#include "perl.h" |
3 |
|
|
#include "XSUB.h" |
4 |
|
|
|
5 |
|
|
#define INIT32 2166136261U |
6 |
|
|
#define MULT32 16777619U |
7 |
|
|
#define INIT64 14695981039346656037U |
8 |
|
|
#define MULT64 1099511628211U |
9 |
|
|
|
10 |
|
|
static UV |
11 |
|
|
fnv1_32 (SV *data, U32 h) |
12 |
|
|
{ |
13 |
|
|
STRLEN l; |
14 |
|
|
U8 *p = (U8 *)SvPVbyte (data, l); |
15 |
|
|
|
16 |
|
|
while (l--) |
17 |
|
|
{ |
18 |
|
|
h *= MULT32; |
19 |
|
|
h ^= *p++; |
20 |
|
|
} |
21 |
|
|
|
22 |
|
|
return h; |
23 |
|
|
} |
24 |
|
|
|
25 |
|
|
static UV |
26 |
|
|
fnv1a_32 (SV *data, U32 h) |
27 |
|
|
{ |
28 |
|
|
STRLEN l; |
29 |
|
|
U8 *p = (U8 *)SvPVbyte (data, l); |
30 |
|
|
|
31 |
|
|
while (l--) |
32 |
|
|
{ |
33 |
|
|
h ^= *p++; |
34 |
|
|
h *= MULT32; |
35 |
|
|
} |
36 |
|
|
|
37 |
|
|
return h; |
38 |
|
|
} |
39 |
|
|
|
40 |
|
|
#if UVSIZE >= 8 |
41 |
|
|
|
42 |
|
|
static UV |
43 |
|
|
fnv1_64 (SV *data, UV h) |
44 |
|
|
{ |
45 |
|
|
STRLEN l; |
46 |
|
|
U8 *p = (U8 *)SvPVbyte (data, l); |
47 |
|
|
|
48 |
|
|
while (l--) |
49 |
|
|
{ |
50 |
|
|
h *= MULT64; |
51 |
|
|
h ^= *p++; |
52 |
|
|
} |
53 |
|
|
|
54 |
|
|
return h; |
55 |
|
|
} |
56 |
|
|
|
57 |
|
|
static UV |
58 |
|
|
fnv1a_64 (SV *data, UV h) |
59 |
|
|
{ |
60 |
|
|
STRLEN l; |
61 |
|
|
U8 *p = (U8 *)SvPVbyte (data, l); |
62 |
|
|
|
63 |
|
|
while (l--) |
64 |
|
|
{ |
65 |
|
|
h ^= *p++; |
66 |
|
|
h *= MULT64; |
67 |
|
|
} |
68 |
|
|
|
69 |
|
|
return h; |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
#endif |
73 |
|
|
|
74 |
|
|
#define fnv0_32 fnv1_32 |
75 |
|
|
#define fnv0_64 fnv1_64 |
76 |
|
|
|
77 |
|
|
static UV |
78 |
|
|
xorfold (UV hash, int bits, int max) |
79 |
|
|
{ |
80 |
|
|
if (bits < max) |
81 |
|
|
hash = ((hash >> (max - bits)) ^ hash) & ((1 << bits) - 1); |
82 |
|
|
|
83 |
|
|
return hash; |
84 |
|
|
} |
85 |
|
|
|
86 |
|
|
#define xorfold_32(hash,bits) xorfold (hash, bits, 32) |
87 |
|
|
#define xorfold_64(hash,bits) xorfold (hash, bits, 64) |
88 |
|
|
|
89 |
|
|
static UV |
90 |
|
|
reduce_32 (U32 hash, U32 range) |
91 |
|
|
{ |
92 |
|
|
U32 retry = 0xffffffffU / range * range; |
93 |
|
|
|
94 |
|
|
while (hash >= retry) |
95 |
|
|
hash = hash * MULT32 + INIT32; |
96 |
|
|
|
97 |
|
|
return hash % range; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
static UV |
101 |
|
|
reduce_64 (UV hash, UV range) |
102 |
|
|
{ |
103 |
|
|
U32 retry = 0xffffffffffffffffU / range * range; |
104 |
|
|
|
105 |
|
|
while (hash >= retry) |
106 |
|
|
hash = hash * MULT64 + INIT64; |
107 |
|
|
|
108 |
|
|
return hash % range; |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
MODULE = Digest::FNV::XS PACKAGE = Digest::FNV::XS |
112 |
|
|
|
113 |
|
|
PROTOTYPES: ENABLE |
114 |
|
|
|
115 |
|
|
UV fnv0_32 (SV *data, SV *init = &PL_sv_undef) |
116 |
|
|
C_ARGS: data, SvUV (init) |
117 |
|
|
|
118 |
|
|
UV fnv1_32 (SV *data, SV *init = &PL_sv_undef) |
119 |
|
|
C_ARGS: data, SvOK (init) ? SvUV (init) : INIT32 |
120 |
|
|
|
121 |
|
|
UV fnv1a_32 (SV *data, SV *init = &PL_sv_undef) |
122 |
|
|
C_ARGS: data, SvOK (init) ? SvUV (init) : INIT32 |
123 |
|
|
|
124 |
|
|
#if UVSIZE >= 8 |
125 |
|
|
|
126 |
|
|
UV fnv0_64 (SV *data, SV *init = &PL_sv_undef) |
127 |
|
|
C_ARGS: data, SvUV (init) |
128 |
|
|
|
129 |
|
|
UV fnv1_64 (SV *data, SV *init = &PL_sv_undef) |
130 |
|
|
C_ARGS: data, SvOK (init) ? SvUV (init) : INIT64 |
131 |
|
|
|
132 |
|
|
UV fnv1a_64 (SV *data, SV *init = &PL_sv_undef) |
133 |
|
|
C_ARGS: data, SvOK (init) ? SvUV (init) : INIT64 |
134 |
|
|
|
135 |
|
|
#endif |
136 |
|
|
|
137 |
|
|
UV xorfold_32 (UV hash, int bits) |
138 |
|
|
|
139 |
|
|
UV xorfold_64 (UV hash, int bits) |
140 |
|
|
|
141 |
|
|
UV reduce_32 (UV hash, UV range) |
142 |
|
|
|
143 |
|
|
UV reduce_64 (UV hash, UV range) |
144 |
|
|
|