wakoopa-rbfnv 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -0
- data/Rakefile +19 -0
- data/ext/fnv/extconf.rb +9 -0
- data/ext/fnv/fnv.c +51 -0
- data/lib/rbfnv.rb +1 -0
- data/test/unit/fnv_test.rb +23 -0
- metadata +74 -0
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# FNV-hash for Ruby
|
2
|
+
|
3
|
+
Provides a C-extension to calculate the FNV-hash in Ruby. Supports only FNV-1 and FNV-1a variants in 64bit.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
require 'rbfnv'
|
8
|
+
Rbfnv.fnv1_64("string") # => -7410993290581388146
|
9
|
+
Rbfnv.fnv1a_64("string") # => 8091808378024623192
|
10
|
+
|
11
|
+
## Credits
|
12
|
+
|
13
|
+
* [robey](https://github.com/robey) for the initial implementation
|
14
|
+
* [menno](https://github.com/menno) for adapting it to 64-bits hashes and bundling it as a gem
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake/extensiontask'
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = "wakoopa-rbfnv"
|
5
|
+
s.authors = ["Robey Pointer", "Menno van der Sman"]
|
6
|
+
s.summary = "FNV hash implementation for ruby"
|
7
|
+
s.version = '0.1.0'
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.files = FileList['lib/**/*.rb', 'ext/**/*', '[A-Z]*', 'test/**/*'].to_a
|
10
|
+
s.extensions = FileList["ext/**/extconf.rb"]
|
11
|
+
s.has_rdoc = false
|
12
|
+
s.require_paths = %w(lib ext)
|
13
|
+
end
|
14
|
+
|
15
|
+
# add your default gem packing task
|
16
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
17
|
+
end
|
18
|
+
|
19
|
+
Rake::ExtensionTask.new('fnv', spec)
|
data/ext/fnv/extconf.rb
ADDED
data/ext/fnv/fnv.c
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#include <stdint.h>
|
2
|
+
#include "ruby.h"
|
3
|
+
|
4
|
+
#define PRIME64 0x100000001b3ULL
|
5
|
+
|
6
|
+
/**
|
7
|
+
* FNV fast hashing algorithm in 64 bits.
|
8
|
+
* @see http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
|
9
|
+
*/
|
10
|
+
static inline uint64_t fnv1_64(const char *data, uint32_t len) {
|
11
|
+
uint64_t rv = 0xcbf29ce484222325ULL;
|
12
|
+
uint64_t i;
|
13
|
+
for (i = 0; i < len; i++) {
|
14
|
+
rv = (rv * PRIME64) ^ (unsigned char)data[i];
|
15
|
+
}
|
16
|
+
return (uint64_t)rv;
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
* FNV fast hashing algorithm in 64 bits, variant with operations reversed.
|
21
|
+
* @see http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
|
22
|
+
*/
|
23
|
+
static inline uint64_t fnv1a_64(const char *data, uint32_t len) {
|
24
|
+
uint64_t rv = 0xcbf29ce484222325ULL;
|
25
|
+
uint64_t i;
|
26
|
+
for (i = 0; i < len; i++) {
|
27
|
+
rv = (rv ^ (unsigned char)data[i]) * PRIME64;
|
28
|
+
}
|
29
|
+
return (uint64_t)rv;
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
/* ----- ruby bindings ----- */
|
34
|
+
|
35
|
+
static VALUE rbfnv_fnv1_64(VALUE self, VALUE data) {
|
36
|
+
return LL2NUM(fnv1_64(RSTRING(data)->ptr, RSTRING(data)->len));
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE rbfnv_fnv1a_64(VALUE self, VALUE data) {
|
40
|
+
return LL2NUM(fnv1a_64(RSTRING(data)->ptr, RSTRING(data)->len));
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
static VALUE rb_rbfnv;
|
45
|
+
|
46
|
+
void Init_fnv() {
|
47
|
+
/* nothing here yet */
|
48
|
+
rb_rbfnv = rb_define_module("Rbfnv");
|
49
|
+
rb_define_singleton_method(rb_rbfnv, "fnv1_64", rbfnv_fnv1_64, 1);
|
50
|
+
rb_define_singleton_method(rb_rbfnv, "fnv1a_64", rbfnv_fnv1a_64, 1);
|
51
|
+
}
|
data/lib/rbfnv.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'fnv.so'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "rbfnv"
|
3
|
+
|
4
|
+
LONGKEY = "the easter island statue memorial tabernacle choir presents"
|
5
|
+
|
6
|
+
class FnvTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_fnv1_64
|
9
|
+
assert_nothing_raised { Rbfnv }
|
10
|
+
assert_equal -3750763034362895579, Rbfnv.fnv1_64("")
|
11
|
+
assert_equal -2822137280848101413, Rbfnv.fnv1_64("cat")
|
12
|
+
assert_equal 6216328457121903479, Rbfnv.fnv1_64(LONGKEY)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_fnv1a_64
|
16
|
+
assert_nothing_raised { Rbfnv }
|
17
|
+
assert_equal -3750763034362895579, Rbfnv.fnv1a_64("")
|
18
|
+
assert_equal -728730910532000985, Rbfnv.fnv1a_64("cat")
|
19
|
+
assert_equal 3347195641695891815, Rbfnv.fnv1a_64(LONGKEY)
|
20
|
+
assert_equal -7368708905145411999, Rbfnv.fnv1a_64("test-string")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wakoopa-rbfnv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Robey Pointer
|
14
|
+
- Menno van der Sman
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-01-10 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description:
|
24
|
+
email:
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions:
|
28
|
+
- ext/fnv/extconf.rb
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- lib/rbfnv.rb
|
33
|
+
- ext/fnv/extconf.rb
|
34
|
+
- ext/fnv/fnv.c
|
35
|
+
- Rakefile
|
36
|
+
- README.md
|
37
|
+
- test/unit/fnv_test.rb
|
38
|
+
has_rdoc: false
|
39
|
+
homepage:
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
- ext
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
hash: 3
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 3
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
version: "0"
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.7
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: FNV hash implementation for ruby
|
73
|
+
test_files: []
|
74
|
+
|