hash_digest 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZGNkZjg5MjcyZmI4ODJiNzFiYTNkNmI3MmE5MzcyZjNiZjRiZDRiMg==
4
+ NzI4MWEwNmNhZGM2NWQ3M2E5ZWRiZTgyODU1OGQ3NjNjMTMzYWQyNg==
5
5
  data.tar.gz: !binary |-
6
- NDExNjc1YzI5OGJlNDQ5ZjUzYzM0MTU1YTYwNGQ2Mjg1MjI0YTdmNg==
6
+ MDhlNjIwYTRjNWY0ZTI1NDlkNDg5NWZkOGZjNzkwMGVmOTJhNDBlNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MTExOWU5MTkyNWRjY2JjYjBlMDRhY2ZhOGU5YmNmNGY0OGUzYjg5ZjlkZTRk
10
- NWU1YTdmMzAxMTkxYzQ4MjBiMDIzODc4MGRiZGUyNTNjZmI1MTgzOGM2M2U5
11
- ODY5YzkyOTcwNGZjMzM4ZGIzMWJmNTU1ZTQ5ZWQzNWI3NDY0YmI=
9
+ YTQyMWEzNzIzNWRmMWIyZWYyZTVjMjdiMDJlMDQ4ODUwYjVhMDc0MmIwNWIx
10
+ MGM0ZmMxYzZjMmZkMDY0MjJmMTE4OWY5YmEzOTQyYjRlMDMxMzA2NjNiM2Fj
11
+ ZGI5Y2VkMjhiNGYxMDk3ODlkOTZkNmFhY2ZmNzY1ZTRmYmVkMmU=
12
12
  data.tar.gz: !binary |-
13
- MTU0NDNjMzg0M2Q2NmEyZWM0OWFlODU3NjU5NDRkMTY0NjlkZjQwOTBiNTVl
14
- MzU3MjY0MDYxNjcyZDdlMTcxOWE4MzJhNWMxYzYwZTgwODM5MDY0N2U1ZmQ4
15
- MjdkOTE4YTg0YTc4YmNmZTgyYTRmNzQ4YmZjODZkZTkxYWFlMmM=
13
+ NjI4MTM2ZDhmMGJiNTI3NzNiN2RlNzg5ZDU2OGRmZTEyOGM2Y2ViOWNiNzgw
14
+ ZWIyZjE2Yzk3MGNmZTUwOThiYTRiODk2NmI5ZDY2Y2YxYmQ3NTQyMTdiNDEw
15
+ MzdkYWJiMDkyMWQ0ODVkZGNiZmNiOTAwNTkxYWY4M2VjMmJmNTg=
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 1.1.3 / 2014-01-14
2
+
3
+ * Enhancements
4
+
5
+ * digest2 is deprecated - too many collisions because we were using MurmurHash3 V32 under the hood
6
+ * digest3 is the replacement - uses SHA1 hexdigest
7
+
1
8
  1.1.2 / 2014-01-06
2
9
 
3
10
  * Bug fixes
@@ -6,51 +6,42 @@ Extracted from [`RemoteTable`](https://github.com/seamusabshere/remote_table).
6
6
 
7
7
  ## Note plz
8
8
 
9
- 1. You should use `HashDigest.digest2` for new applications. `hexdigest` is legacy.
10
- 2. `digest2`, unlike its predecessor, is CASE SENSITIVE.
9
+ 1. You should use `HashDigest.digest3` for new applications. `hexdigest` and `digest2` are legacy.
10
+ 2. `digest2` is CASE SENSITIVE and has relatively high level of collisions - not recommended.
11
11
 
12
12
  ## Example
13
13
 
14
14
  ### Indifferent to key type
15
15
 
16
- >> HashDigest.digest2(:a => 1)
17
- => "1s05qdo"
18
- >> HashDigest.digest2('a' => 1)
19
- => "1s05qdo"
16
+ >> HashDigest.digest3(:a => 1)
17
+ => "86eda770a6060824b090dd4df091e3bd4121279c"
18
+ >> HashDigest.digest3('a' => 1)
19
+ => "86eda770a6060824b090dd4df091e3bd4121279c"
20
20
 
21
21
  ### Indifferent to key order
22
22
 
23
- >> HashDigest.digest2(:a => 1, 'b' => 2)
24
- => "fkqncr"
25
- >> HashDigest.digest2(:b => 2, 'a' => 1)
26
- => "fkqncr"
23
+ >> HashDigest.digest3(:a => 1, 'b' => 2)
24
+ => "d53cf64e768f4ef09c806bbe12258c78211b2690"
25
+ >> HashDigest.digest3(:b => 2, 'a' => 1)
26
+ => "d53cf64e768f4ef09c806bbe12258c78211b2690"
27
27
 
28
28
  ## Speed
29
29
 
30
30
  If you're **not** on JRuby, having [`EscapeUtils`](https://github.com/brianmario/escape_utils) in your `Gemfile` will make things much faster.
31
31
 
32
- ### With EscapeUtils (MRI, doesn't work on JRuby)
33
-
34
- HashDigest.digest2 2492 i/100ms
35
- HashDigest.hexdigest 2276 i/100ms
36
-
37
- ### With stdlib's CGI (JRuby)
38
-
39
- HashDigest.digest2 645 i/100ms
40
- HashDigest.hexdigest 213 i/100ms
41
-
42
- ### With stdlib's CGI (MRI)
32
+ ## Algorithm
43
33
 
44
- HashDigest.digest2 531 i/100ms
45
- HashDigest.hexdigest 513 i/100ms
34
+ ### digest3
46
35
 
47
- ## Algorithm
36
+ 1. Represent the hash as a URL querystring
37
+ 2. Sort by key
38
+ 3. SHA1 hexdigest
48
39
 
49
- ### digest2 (current)
40
+ ### digest2 (deprecated and not recommended)
50
41
 
51
42
  1. Represent the hash as a URL querystring
52
43
  2. Sort by key
53
- 3. [MurmurHash3](http://en.wikipedia.org/wiki/MurmurHash)
44
+ 3. [MurmurHash3](http://en.wikipedia.org/wiki/MurmurHash) V32 (this turned out to have too many collisions)
54
45
  4. Convert to base 36 to save space
55
46
 
56
47
  Note: non-cryptographic and variable length. CASE SENSITIVE.
@@ -1,4 +1,5 @@
1
1
  require 'digest/md5'
2
+ require 'digest/sha1'
2
3
  require 'murmurhash3'
3
4
  # see below for requiring either cgi (on JRuby) or escape_utils (if available)
4
5
 
@@ -6,17 +7,26 @@ require "hash_digest/version"
6
7
 
7
8
  module HashDigest
8
9
  # CURRENT
10
+ def self.as_digest3(obj)
11
+ obj.to_hash_digest_query
12
+ end
13
+
14
+ # CURRENT
15
+ def self.digest3(obj)
16
+ ::Digest::SHA1.hexdigest as_digest2(obj)
17
+ end
9
18
 
19
+ # LEGACY
10
20
  def self.as_digest2(obj)
11
21
  obj.to_hash_digest_query
12
22
  end
13
23
 
24
+ # LEGACY
14
25
  def self.digest2(obj)
15
26
  ::MurmurHash3::V32.str_hash(as_digest2(obj)).to_s 36
16
27
  end
17
28
 
18
29
  # LEGACY
19
-
20
30
  def self.as_digest1(obj)
21
31
  ordered_list = case obj
22
32
  when ::Hash
@@ -35,6 +45,7 @@ module HashDigest
35
45
  ordered_list.join '&'
36
46
  end
37
47
 
48
+ # LEGACY
38
49
  def self.hexdigest(obj)
39
50
  ::Digest::MD5.hexdigest as_digest1(obj)
40
51
  end
@@ -1,3 +1,3 @@
1
1
  module HashDigest
2
- VERSION = "1.1.2"
2
+ VERSION = "1.1.3"
3
3
  end
@@ -5,8 +5,8 @@ require 'stringio'
5
5
  describe HashDigest do
6
6
  include TestHelper
7
7
 
8
- describe '.digest2' do
9
- it "is much faster than .hexdigest" do
8
+ describe 'speed' do
9
+ it "improves as we get older" do
10
10
  hsh = { 'a' => 1, :b => { foo: :bar, zoo: 'animal' }, ";b\n`&" => { foo: :bar, zoo: "==&ani!!.;&mal\n" } }
11
11
  begin
12
12
  old_stdout = $stdout
@@ -14,6 +14,7 @@ describe HashDigest do
14
14
  Benchmark.ips do |x|
15
15
  x.report("HashDigest.hexdigest") { HashDigest.hexdigest(hsh) }
16
16
  x.report("HashDigest.digest2") { HashDigest.digest2(hsh) }
17
+ x.report("HashDigest.digest3") { HashDigest.digest3(hsh) }
17
18
  end
18
19
  $stdout.rewind
19
20
  result = $stdout.read
@@ -56,11 +57,11 @@ describe HashDigest do
56
57
 
57
58
  describe 'indifference to' do
58
59
  it 'key type' do
59
- HashDigest.as_digest2(:a => 1, 'b' => 2).must_equal(HashDigest.as_digest2('a' => 1, :b => 2))
60
+ HashDigest.as_digest3(:a => 1, 'b' => 2).must_equal(HashDigest.as_digest3('a' => 1, :b => 2))
60
61
  end
61
62
 
62
63
  it 'key order' do
63
- HashDigest.as_digest2(:a => 1, 'b' => 2).must_equal(HashDigest.as_digest2(:b => 2, 'a' => 1))
64
+ HashDigest.as_digest3(:a => 1, 'b' => 2).must_equal(HashDigest.as_digest3(:b => 2, 'a' => 1))
64
65
  end
65
66
 
66
67
  [
@@ -72,7 +73,7 @@ describe HashDigest do
72
73
  it "trivial difference between #{a} and #{b}" do
73
74
  assert_same_as_old a
74
75
  assert_same_as_old b
75
- HashDigest.as_digest2(b).must_equal(HashDigest.as_digest2(b))
76
+ HashDigest.as_digest3(b).must_equal(HashDigest.as_digest3(b))
76
77
  end
77
78
  end
78
79
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hash_digest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seamus Abshere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-06 00:00:00.000000000 Z
11
+ date: 2014-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: murmurhash3