digest-murmurhash 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/Rakefile +11 -1
- data/digest-murmurhash.gemspec +3 -3
- data/ext/digest/murmurhash/extconf.rb +1 -2
- data/ext/digest/murmurhash/murmurhash.c +253 -0
- data/ext/digest/murmurhash/murmurhash.h +52 -35
- data/ext/digest/murmurhash/murmurhash1.c +18 -54
- data/ext/digest/murmurhash/murmurhash2.c +17 -56
- data/ext/digest/murmurhash/murmurhash2a.c +18 -42
- data/ext/digest/murmurhash/murmurhash64a.c +87 -0
- data/ext/digest/murmurhash/murmurhash64a.h +13 -0
- data/ext/digest/murmurhash/murmurhash64b.c +93 -0
- data/ext/digest/murmurhash/murmurhash64b.h +13 -0
- data/ext/digest/murmurhash/murmurhash_aligned2.c +87 -0
- data/ext/digest/murmurhash/murmurhash_aligned2.h +13 -0
- data/ext/digest/murmurhash/murmurhash_neutral2.c +87 -0
- data/ext/digest/murmurhash/murmurhash_neutral2.h +13 -0
- data/lib/digest/murmurhash/version.rb +1 -1
- data/spec/bench.rb +21 -31
- data/spec/digest_spec.rb +54 -34
- data/spec/exception_spec.rb +19 -4
- data/spec/mem_spec.rb +3 -6
- data/spec/spec_helper.rb +21 -0
- metadata +15 -7
- data/ext/digest/murmurhash/init.c +0 -39
@@ -4,31 +4,24 @@
|
|
4
4
|
|
5
5
|
#include "murmurhash2.h"
|
6
6
|
|
7
|
-
static inline size_t
|
8
|
-
murmur2(uint32_t h, uint32_t k, const uint8_t r)
|
9
|
-
{
|
10
|
-
const uint32_t m = MURMURHASH_MAGIC;
|
11
|
-
k *= m;
|
12
|
-
k ^= k >> r;
|
13
|
-
k *= m;
|
14
|
-
|
15
|
-
h *= m;
|
16
|
-
h ^= k;
|
17
|
-
return h;
|
18
|
-
}
|
19
|
-
|
20
7
|
static uint32_t
|
21
|
-
murmur_hash_process2(const char *data, uint32_t length)
|
8
|
+
murmur_hash_process2(const char *data, uint32_t length, uint32_t seed)
|
22
9
|
{
|
23
10
|
const uint32_t m = MURMURHASH_MAGIC;
|
24
11
|
const uint8_t r = 24;
|
25
12
|
uint32_t h, k;
|
26
13
|
|
27
|
-
h =
|
14
|
+
h = seed ^ length;
|
28
15
|
|
29
16
|
while (4 <= length) {
|
30
17
|
k = *(uint32_t*)data;
|
31
|
-
|
18
|
+
k *= m;
|
19
|
+
k ^= k >> r;
|
20
|
+
k *= m;
|
21
|
+
|
22
|
+
h *= m;
|
23
|
+
h ^= k;
|
24
|
+
|
32
25
|
data += 4;
|
33
26
|
length -= 4;
|
34
27
|
}
|
@@ -50,49 +43,27 @@ murmur_hash_process2(const char *data, uint32_t length)
|
|
50
43
|
VALUE
|
51
44
|
murmur2_finish(VALUE self)
|
52
45
|
{
|
53
|
-
uint32_t h;
|
54
46
|
uint8_t digest[4];
|
55
|
-
|
56
|
-
|
57
|
-
h = murmur_hash_process2(ptr->buffer, ptr->p - ptr->buffer);
|
58
|
-
|
59
|
-
digest[0] = h >> 24;
|
60
|
-
digest[1] = h >> 16;
|
61
|
-
digest[2] = h >> 8;
|
62
|
-
digest[3] = h;
|
47
|
+
uint64_t h;
|
63
48
|
|
49
|
+
h = _murmur_finish32(self, murmur_hash_process2);
|
50
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
64
51
|
return rb_str_new((const char*) digest, 4);
|
65
52
|
}
|
66
53
|
|
67
54
|
VALUE
|
68
55
|
murmur2_to_i(VALUE self)
|
69
56
|
{
|
70
|
-
|
71
|
-
return UINT2NUM(murmur_hash_process2(ptr->buffer, ptr->p - ptr->buffer));
|
57
|
+
return ULONG2NUM(_murmur_finish32(self, murmur_hash_process2));
|
72
58
|
}
|
73
59
|
|
74
60
|
VALUE
|
75
61
|
murmur2_s_digest(int argc, VALUE *argv, VALUE klass)
|
76
62
|
{
|
77
|
-
VALUE str;
|
78
|
-
uint32_t h;
|
79
63
|
uint8_t digest[4];
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
str = *argv++;
|
85
|
-
argc--;
|
86
|
-
|
87
|
-
StringValue(str);
|
88
|
-
|
89
|
-
h = murmur_hash_process2(RSTRING_PTR(str), RSTRING_LEN(str));
|
90
|
-
|
91
|
-
digest[0] = h >> 24;
|
92
|
-
digest[1] = h >> 16;
|
93
|
-
digest[2] = h >> 8;
|
94
|
-
digest[3] = h;
|
95
|
-
|
64
|
+
uint32_t h;
|
65
|
+
h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process2);
|
66
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
96
67
|
return rb_str_new((const char*) digest, 4);
|
97
68
|
}
|
98
69
|
|
@@ -105,16 +76,6 @@ murmur2_s_hexdigest(int argc, VALUE *argv, VALUE klass)
|
|
105
76
|
VALUE
|
106
77
|
murmur2_s_rawdigest(int argc, VALUE *argv, VALUE klass)
|
107
78
|
{
|
108
|
-
|
109
|
-
|
110
|
-
if (argc < 1)
|
111
|
-
rb_raise(rb_eArgError, "no data given");
|
112
|
-
|
113
|
-
str = *argv++;
|
114
|
-
argc--;
|
115
|
-
|
116
|
-
StringValue(str);
|
117
|
-
|
118
|
-
return UINT2NUM(murmur_hash_process2(RSTRING_PTR(str), RSTRING_LEN(str)));
|
79
|
+
return ULONG2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process2));
|
119
80
|
}
|
120
81
|
|
@@ -7,7 +7,7 @@
|
|
7
7
|
#define mmix(h,k) { k *= m; k ^= k >> r; k *= m; h *= m; h ^= k; }
|
8
8
|
|
9
9
|
static uint32_t
|
10
|
-
murmur_hash_process2a(const
|
10
|
+
murmur_hash_process2a(const char *key, uint32_t length, uint32_t seed)
|
11
11
|
{
|
12
12
|
const uint32_t m = MURMURHASH_MAGIC;
|
13
13
|
const uint8_t r = 24;
|
@@ -15,7 +15,7 @@ murmur_hash_process2a(const void *key, uint32_t length)
|
|
15
15
|
const unsigned char *data = (const unsigned char *) key;
|
16
16
|
|
17
17
|
l = length;
|
18
|
-
h =
|
18
|
+
h = seed;
|
19
19
|
|
20
20
|
while (4 <= length) {
|
21
21
|
k = *(uint32_t*)data;
|
@@ -41,52 +41,38 @@ murmur_hash_process2a(const void *key, uint32_t length)
|
|
41
41
|
return h;
|
42
42
|
}
|
43
43
|
|
44
|
+
static uint32_t
|
45
|
+
_murmur2a_finish(VALUE self)
|
46
|
+
{
|
47
|
+
const char *seed = RSTRING_PTR(murmur_seed_get32(self));
|
48
|
+
MURMURHASH(self, ptr);
|
49
|
+
return murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer, *(uint32_t*)seed);
|
50
|
+
}
|
51
|
+
|
44
52
|
VALUE
|
45
53
|
murmur2a_finish(VALUE self)
|
46
54
|
{
|
47
|
-
uint32_t h;
|
48
55
|
uint8_t digest[4];
|
49
|
-
|
50
|
-
|
51
|
-
h = murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer);
|
52
|
-
|
53
|
-
digest[0] = h >> 24;
|
54
|
-
digest[1] = h >> 16;
|
55
|
-
digest[2] = h >> 8;
|
56
|
-
digest[3] = h;
|
56
|
+
uint64_t h;
|
57
57
|
|
58
|
+
h = _murmur2a_finish(self);
|
59
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
58
60
|
return rb_str_new((const char*) digest, 4);
|
59
61
|
}
|
60
62
|
|
61
63
|
VALUE
|
62
64
|
murmur2a_to_i(VALUE self)
|
63
65
|
{
|
64
|
-
|
65
|
-
return UINT2NUM(murmur_hash_process2a(ptr->buffer, ptr->p - ptr->buffer));
|
66
|
+
return ULONG2NUM(_murmur2a_finish(self));
|
66
67
|
}
|
67
68
|
|
68
69
|
VALUE
|
69
70
|
murmur2a_s_digest(int argc, VALUE *argv, VALUE klass)
|
70
71
|
{
|
71
|
-
VALUE str;
|
72
|
-
uint32_t h;
|
73
72
|
uint8_t digest[4];
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
str = *argv++;
|
79
|
-
argc--;
|
80
|
-
|
81
|
-
StringValue(str);
|
82
|
-
|
83
|
-
h = murmur_hash_process2a(RSTRING_PTR(str), RSTRING_LEN(str));
|
84
|
-
|
85
|
-
digest[0] = h >> 24;
|
86
|
-
digest[1] = h >> 16;
|
87
|
-
digest[2] = h >> 8;
|
88
|
-
digest[3] = h;
|
89
|
-
|
73
|
+
uint32_t h;
|
74
|
+
h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process2a);
|
75
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
90
76
|
return rb_str_new((const char*) digest, 4);
|
91
77
|
}
|
92
78
|
|
@@ -99,16 +85,6 @@ murmur2a_s_hexdigest(int argc, VALUE *argv, VALUE klass)
|
|
99
85
|
VALUE
|
100
86
|
murmur2a_s_rawdigest(int argc, VALUE *argv, VALUE klass)
|
101
87
|
{
|
102
|
-
|
103
|
-
|
104
|
-
if (argc < 1)
|
105
|
-
rb_raise(rb_eArgError, "no data given");
|
106
|
-
|
107
|
-
str = *argv++;
|
108
|
-
argc--;
|
109
|
-
|
110
|
-
StringValue(str);
|
111
|
-
|
112
|
-
return UINT2NUM(murmur_hash_process2a(RSTRING_PTR(str), RSTRING_LEN(str)));
|
88
|
+
return ULL2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process2a));
|
113
89
|
}
|
114
90
|
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/*
|
2
|
+
* MurmurHash64A (C) Austin Appleby
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "murmurhash64a.h"
|
6
|
+
|
7
|
+
static uint64_t
|
8
|
+
murmur_hash_process64a(const char *key, uint32_t len, uint64_t seed)
|
9
|
+
{
|
10
|
+
const uint64_t m = MURMURHASH_MAGIC64A;
|
11
|
+
const int r = 47;
|
12
|
+
|
13
|
+
uint64_t h = seed ^ (len * m);
|
14
|
+
|
15
|
+
const uint64_t * data = (const uint64_t *)key;
|
16
|
+
const uint64_t * end = data + (len/8);
|
17
|
+
|
18
|
+
while(data != end)
|
19
|
+
{
|
20
|
+
uint64_t k = *data++;
|
21
|
+
|
22
|
+
k *= m;
|
23
|
+
k ^= k >> r;
|
24
|
+
k *= m;
|
25
|
+
|
26
|
+
h ^= k;
|
27
|
+
h *= m;
|
28
|
+
}
|
29
|
+
|
30
|
+
const unsigned char * data2 = (const unsigned char*)data;
|
31
|
+
|
32
|
+
switch(len & 7) {
|
33
|
+
case 7: h ^= (uint64_t)((uint64_t)data2[6] << (uint64_t)48);
|
34
|
+
case 6: h ^= (uint64_t)((uint64_t)data2[5] << (uint64_t)40);
|
35
|
+
case 5: h ^= (uint64_t)((uint64_t)data2[4] << (uint64_t)32);
|
36
|
+
case 4: h ^= (uint64_t)((uint64_t)data2[3] << (uint64_t)24);
|
37
|
+
case 3: h ^= (uint64_t)((uint64_t)data2[2] << (uint64_t)16);
|
38
|
+
case 2: h ^= (uint64_t)((uint64_t)data2[1] << (uint64_t)8 );
|
39
|
+
case 1: h ^= (uint64_t)((uint64_t)data2[0] );
|
40
|
+
h *= m;
|
41
|
+
};
|
42
|
+
|
43
|
+
h ^= h >> r;
|
44
|
+
h *= m;
|
45
|
+
h ^= h >> r;
|
46
|
+
|
47
|
+
return h;
|
48
|
+
}
|
49
|
+
|
50
|
+
VALUE
|
51
|
+
murmur64a_finish(VALUE self)
|
52
|
+
{
|
53
|
+
uint8_t digest[8];
|
54
|
+
uint64_t h;
|
55
|
+
|
56
|
+
h = _murmur_finish64(self, murmur_hash_process64a);
|
57
|
+
ASSINE_BY_ENDIAN_64(digest, h);
|
58
|
+
return rb_str_new((const char*) digest, 8);
|
59
|
+
}
|
60
|
+
|
61
|
+
VALUE
|
62
|
+
murmur64a_to_i(VALUE self)
|
63
|
+
{
|
64
|
+
return ULL2NUM(_murmur_finish64(self, murmur_hash_process64a));
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE
|
68
|
+
murmur64a_s_digest(int argc, VALUE *argv, VALUE klass)
|
69
|
+
{
|
70
|
+
uint8_t digest[8];
|
71
|
+
uint64_t h;
|
72
|
+
h = _murmur_s_digest64(argc, argv, klass, murmur_hash_process64a);
|
73
|
+
ASSINE_BY_ENDIAN_64(digest, h);
|
74
|
+
return rb_str_new((const char*) digest, 8);
|
75
|
+
}
|
76
|
+
|
77
|
+
VALUE
|
78
|
+
murmur64a_s_hexdigest(int argc, VALUE *argv, VALUE klass)
|
79
|
+
{
|
80
|
+
return hexencode_str_new(murmur64a_s_digest(argc, argv, klass));
|
81
|
+
}
|
82
|
+
|
83
|
+
VALUE
|
84
|
+
murmur64a_s_rawdigest(int argc, VALUE *argv, VALUE klass)
|
85
|
+
{
|
86
|
+
return ULL2NUM(_murmur_s_digest64(argc, argv, klass, murmur_hash_process64a));
|
87
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef MURMURHASH64A_INCLUDED
|
2
|
+
# define MURMURHASH64A_INCLUDED
|
3
|
+
|
4
|
+
#include "murmurhash.h"
|
5
|
+
|
6
|
+
VALUE murmur64a_finish(VALUE self);
|
7
|
+
VALUE murmur64a_to_i(VALUE self);
|
8
|
+
VALUE murmur64a_s_digest(int argc, VALUE *argv, VALUE klass);
|
9
|
+
VALUE murmur64a_s_hexdigest(int argc, VALUE *argv, VALUE klass);
|
10
|
+
VALUE murmur64a_s_rawdigest(int argc, VALUE *argv, VALUE klass);
|
11
|
+
|
12
|
+
#endif /* ifndef MURMURHASH64A_INCLUDED */
|
13
|
+
|
@@ -0,0 +1,93 @@
|
|
1
|
+
/*
|
2
|
+
* MurmurHash64B (C) Austin Appleby
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "murmurhash64b.h"
|
6
|
+
|
7
|
+
uint64_t
|
8
|
+
murmur_hash_process64b(const char * key, uint32_t len, uint64_t seed)
|
9
|
+
{
|
10
|
+
const uint32_t m = MURMURHASH_MAGIC;
|
11
|
+
const int r = 24;
|
12
|
+
|
13
|
+
uint32_t h1 = (uint32_t)(seed) ^ len;
|
14
|
+
uint32_t h2 = (uint32_t)(seed >> 32);
|
15
|
+
|
16
|
+
const uint32_t * data = (const uint32_t *)key;
|
17
|
+
|
18
|
+
while(len >= 8) {
|
19
|
+
uint32_t k1 = *data++;
|
20
|
+
k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
21
|
+
h1 *= m; h1 ^= k1;
|
22
|
+
len -= 4;
|
23
|
+
|
24
|
+
uint32_t k2 = *data++;
|
25
|
+
k2 *= m; k2 ^= k2 >> r; k2 *= m;
|
26
|
+
h2 *= m; h2 ^= k2;
|
27
|
+
len -= 4;
|
28
|
+
}
|
29
|
+
|
30
|
+
if(len >= 4) {
|
31
|
+
uint32_t k1 = *data++;
|
32
|
+
k1 *= m; k1 ^= k1 >> r; k1 *= m;
|
33
|
+
h1 *= m; h1 ^= k1;
|
34
|
+
len -= 4;
|
35
|
+
}
|
36
|
+
|
37
|
+
switch(len) {
|
38
|
+
case 3: h2 ^= ((unsigned char*)data)[2] << 16;
|
39
|
+
case 2: h2 ^= ((unsigned char*)data)[1] << 8;
|
40
|
+
case 1: h2 ^= ((unsigned char*)data)[0];
|
41
|
+
h2 *= m;
|
42
|
+
};
|
43
|
+
|
44
|
+
h1 ^= h2 >> 18; h1 *= m;
|
45
|
+
h2 ^= h1 >> 22; h2 *= m;
|
46
|
+
h1 ^= h2 >> 17; h1 *= m;
|
47
|
+
h2 ^= h1 >> 19; h2 *= m;
|
48
|
+
|
49
|
+
uint64_t h = h1;
|
50
|
+
|
51
|
+
h = (h << 32) | h2;
|
52
|
+
|
53
|
+
return h;
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE
|
57
|
+
murmur64b_finish(VALUE self)
|
58
|
+
{
|
59
|
+
uint8_t digest[8];
|
60
|
+
uint64_t h;
|
61
|
+
|
62
|
+
h = _murmur_finish64(self, murmur_hash_process64b);
|
63
|
+
ASSINE_BY_ENDIAN_64(digest, h);
|
64
|
+
return rb_str_new((const char*) digest, 8);
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE
|
68
|
+
murmur64b_to_i(VALUE self)
|
69
|
+
{
|
70
|
+
return ULL2NUM(_murmur_finish64(self, murmur_hash_process64b));
|
71
|
+
}
|
72
|
+
|
73
|
+
VALUE
|
74
|
+
murmur64b_s_digest(int argc, VALUE *argv, VALUE klass)
|
75
|
+
{
|
76
|
+
uint8_t digest[8];
|
77
|
+
uint64_t h;
|
78
|
+
h = _murmur_s_digest64(argc, argv, klass, murmur_hash_process64b);
|
79
|
+
ASSINE_BY_ENDIAN_64(digest, h);
|
80
|
+
return rb_str_new((const char*) digest, 8);
|
81
|
+
}
|
82
|
+
|
83
|
+
VALUE
|
84
|
+
murmur64b_s_hexdigest(int argc, VALUE *argv, VALUE klass)
|
85
|
+
{
|
86
|
+
return hexencode_str_new(murmur64b_s_digest(argc, argv, klass));
|
87
|
+
}
|
88
|
+
|
89
|
+
VALUE
|
90
|
+
murmur64b_s_rawdigest(int argc, VALUE *argv, VALUE klass)
|
91
|
+
{
|
92
|
+
return ULL2NUM(_murmur_s_digest64(argc, argv, klass, murmur_hash_process64b));
|
93
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#ifndef MURMURHASH64B_INCLUDED
|
2
|
+
# define MURMURHASH64B_INCLUDED
|
3
|
+
|
4
|
+
#include "murmurhash.h"
|
5
|
+
|
6
|
+
VALUE murmur64b_finish(VALUE self);
|
7
|
+
VALUE murmur64b_to_i(VALUE self);
|
8
|
+
VALUE murmur64b_s_digest(int argc, VALUE *argv, VALUE klass);
|
9
|
+
VALUE murmur64b_s_hexdigest(int argc, VALUE *argv, VALUE klass);
|
10
|
+
VALUE murmur64b_s_rawdigest(int argc, VALUE *argv, VALUE klass);
|
11
|
+
|
12
|
+
#endif /* ifndef MURMURHASH64B_INCLUDED */
|
13
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/*
|
2
|
+
* MurmurHashAligned2 (C) Austin Appleby
|
3
|
+
*/
|
4
|
+
|
5
|
+
#include "murmurhash_aligned2.h"
|
6
|
+
|
7
|
+
uint32_t
|
8
|
+
murmur_hash_process_aligned2(const char * key, uint32_t len, uint32_t seed)
|
9
|
+
{
|
10
|
+
const uint32_t m = 0x5bd1e995;
|
11
|
+
const int r = 24;
|
12
|
+
|
13
|
+
uint32_t h = seed ^ len;
|
14
|
+
|
15
|
+
const unsigned char * data = (const unsigned char *)key;
|
16
|
+
|
17
|
+
while(len >= 4) {
|
18
|
+
uint32_t k;
|
19
|
+
|
20
|
+
k = data[0];
|
21
|
+
k |= data[1] << 8;
|
22
|
+
k |= data[2] << 16;
|
23
|
+
k |= data[3] << 24;
|
24
|
+
|
25
|
+
k *= m;
|
26
|
+
k ^= k >> r;
|
27
|
+
k *= m;
|
28
|
+
|
29
|
+
h *= m;
|
30
|
+
h ^= k;
|
31
|
+
|
32
|
+
data += 4;
|
33
|
+
len -= 4;
|
34
|
+
}
|
35
|
+
|
36
|
+
switch(len) {
|
37
|
+
case 3: h ^= data[2] << 16;
|
38
|
+
case 2: h ^= data[1] << 8;
|
39
|
+
case 1: h ^= data[0];
|
40
|
+
h *= m;
|
41
|
+
};
|
42
|
+
|
43
|
+
h ^= h >> 13;
|
44
|
+
h *= m;
|
45
|
+
h ^= h >> 15;
|
46
|
+
|
47
|
+
return h;
|
48
|
+
}
|
49
|
+
|
50
|
+
VALUE
|
51
|
+
murmur_aligned2_finish(VALUE self)
|
52
|
+
{
|
53
|
+
uint8_t digest[4];
|
54
|
+
uint32_t h;
|
55
|
+
|
56
|
+
h = _murmur_finish32(self, murmur_hash_process_aligned2);
|
57
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
58
|
+
return rb_str_new((const char*) digest, 4);
|
59
|
+
}
|
60
|
+
|
61
|
+
VALUE
|
62
|
+
murmur_aligned2_to_i(VALUE self)
|
63
|
+
{
|
64
|
+
return ULL2NUM(_murmur_finish32(self, murmur_hash_process_aligned2));
|
65
|
+
}
|
66
|
+
|
67
|
+
VALUE
|
68
|
+
murmur_aligned2_s_digest(int argc, VALUE *argv, VALUE klass)
|
69
|
+
{
|
70
|
+
uint8_t digest[4];
|
71
|
+
uint64_t h;
|
72
|
+
h = _murmur_s_digest32(argc, argv, klass, murmur_hash_process_aligned2);
|
73
|
+
ASSINE_BY_ENDIAN_32(digest, h);
|
74
|
+
return rb_str_new((const char*) digest, 4);
|
75
|
+
}
|
76
|
+
|
77
|
+
VALUE
|
78
|
+
murmur_aligned2_s_hexdigest(int argc, VALUE *argv, VALUE klass)
|
79
|
+
{
|
80
|
+
return hexencode_str_new(murmur_aligned2_s_digest(argc, argv, klass));
|
81
|
+
}
|
82
|
+
|
83
|
+
VALUE
|
84
|
+
murmur_aligned2_s_rawdigest(int argc, VALUE *argv, VALUE klass)
|
85
|
+
{
|
86
|
+
return ULL2NUM(_murmur_s_digest32(argc, argv, klass, murmur_hash_process_aligned2));
|
87
|
+
}
|