ruby_identicon 0.0.3 → 0.0.4
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/Gemfile +4 -0
- data/README.md +7 -3
- data/lib/ruby_identicon.rb +31 -30
- data/lib/ruby_identicon/version.rb +1 -1
- data/lib/siphash.rb +8 -10
- data/ruby_identicon.gemspec +3 -2
- data/ruby_identicon.rb +14 -0
- data/spec/ruby_identicon_spec.rb +38 -32
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 864f1543ca10712e1e4db984ce599ef5a49b23ae
|
4
|
+
data.tar.gz: 3009ca72274f11cfaa090fa275c9e64783d218fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68aa48240830d7c2df66e9244aff4da2042aebf65eebbb755da1f5a7d3ea0335a2f9297b6b6795c213e478c256b8db3bbdaecb3e0e8d87c382e4b9a93b229599
|
7
|
+
data.tar.gz: dda0a4b288e810f63eab0728c7574d79b0fd082337a8a843065a5d45193da8259abc717ff1998fe7a5feafabb7a34cfa8c22892698681855bc883b86a21b849b
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -36,10 +36,14 @@ Creating an identicon and saving to png
|
|
36
36
|
Creating an identicon and returning a binary string
|
37
37
|
|
38
38
|
blob = RubyIdenticon.create("RubyIdenticon")
|
39
|
-
|
39
|
+
|
40
40
|
# optional, save to a file
|
41
41
|
File.open("ruby_identicon.png", "wb") do |f| f.write(blob) end
|
42
42
|
|
43
|
+
Creating an identicon and returns in base64 format
|
44
|
+
|
45
|
+
base64 = RubyIdenticon.create_base64("RubyIdenticon")
|
46
|
+
|
43
47
|
## Customising the identicon
|
44
48
|
|
45
49
|
The identicon can be customised by passing additional options
|
@@ -49,10 +53,10 @@ The identicon can be customised by passing additional options
|
|
49
53
|
grid_size: (Integer, default 7) the number of rows and columns in the identicon, minimum 4, maximum 9
|
50
54
|
square_size: (Integer, default 50) the size in pixels of each square that makes up the identicon
|
51
55
|
key: (String) a 16 byte key used by siphash when calculating the hash value (see note below)
|
52
|
-
|
56
|
+
|
53
57
|
Varying the key ensures uniqueness of an identicon for a given title, it is assumed desirable for different applications
|
54
58
|
to use a different key.
|
55
|
-
|
59
|
+
|
56
60
|
Example
|
57
61
|
|
58
62
|
blob = RubyIdenticon.create("identicons are great!", grid_size: 5, square_size: 70, background_color: 0xf0f0f0ff, key: "1234567890123456")
|
data/lib/ruby_identicon.rb
CHANGED
@@ -25,6 +25,11 @@
|
|
25
25
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
26
26
|
#++
|
27
27
|
|
28
|
+
require 'ruby_identicon/version'
|
29
|
+
require 'chunky_png'
|
30
|
+
require 'siphash'
|
31
|
+
require 'base64'
|
32
|
+
|
28
33
|
#
|
29
34
|
# A Ruby implementation of go-identicon
|
30
35
|
#
|
@@ -40,13 +45,8 @@
|
|
40
45
|
# The grid and square sizes can be varied to create identicons of
|
41
46
|
# differing size.
|
42
47
|
#
|
43
|
-
|
44
|
-
require "ruby_identicon/version"
|
45
|
-
require "chunky_png"
|
46
|
-
require "siphash"
|
47
|
-
|
48
48
|
module RubyIdenticon
|
49
|
-
# the default
|
49
|
+
# the default options used when creating identicons
|
50
50
|
#
|
51
51
|
# background_color: (Integer, default 0) the background color of the identicon in rgba notation (e.g. xffffffff for white)
|
52
52
|
# border_size: (Integer, default 35) the size in pixels to leave as an empty border around the identicon image
|
@@ -57,8 +57,7 @@ module RubyIdenticon
|
|
57
57
|
# varying the key ensures uniqueness of an identicon for a given title, it is assumed desirable for different applications
|
58
58
|
# to use a different key.
|
59
59
|
#
|
60
|
-
|
61
|
-
DEFAULT_PARAMETERS = {
|
60
|
+
DEFAULT_OPTIONS = {
|
62
61
|
border_size: 35,
|
63
62
|
square_size: 50,
|
64
63
|
grid_size: 7,
|
@@ -69,41 +68,39 @@ module RubyIdenticon
|
|
69
68
|
# create an identicon png and save it to the given filename
|
70
69
|
#
|
71
70
|
# Example:
|
72
|
-
# >> RubyIdenticon.create_and_save(
|
71
|
+
# >> RubyIdenticon.create_and_save('identicons are great!', 'test_identicon.png')
|
73
72
|
# => result (Boolean)
|
74
73
|
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
|
74
|
+
# @param title [string] the string value to be represented as an identicon
|
75
|
+
# @param filename [string] the full path and filename to save the identicon png to
|
76
|
+
# @param options [hash] additional options for the identicon
|
77
|
+
#
|
80
78
|
def self.create_and_save(title, filename, options = {})
|
81
|
-
raise
|
79
|
+
raise 'filename cannot be nil' if filename == nil
|
82
80
|
|
83
81
|
blob = create(title, options)
|
84
82
|
return false if blob == nil
|
85
83
|
|
86
|
-
File.open(filename,
|
84
|
+
File.open(filename, 'wb') { |f| f.write(blob) }
|
87
85
|
end
|
88
86
|
|
89
87
|
# create an identicon png and return it as a binary string
|
90
88
|
#
|
91
89
|
# Example:
|
92
|
-
# >> RubyIdenticon.create(
|
90
|
+
# >> RubyIdenticon.create('identicons are great!')
|
93
91
|
# => binary blob (String)
|
94
92
|
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
|
93
|
+
# @param title [string] the string value to be represented as an identicon
|
94
|
+
# @param options [hash] additional options for the identicon
|
95
|
+
#
|
99
96
|
def self.create(title, options = {})
|
100
|
-
options =
|
101
|
-
|
102
|
-
raise
|
103
|
-
raise
|
104
|
-
raise
|
105
|
-
raise
|
106
|
-
raise
|
97
|
+
options = DEFAULT_OPTIONS.merge(options)
|
98
|
+
|
99
|
+
raise 'title cannot be nil' if title == nil
|
100
|
+
raise 'key is nil or less than 16 bytes' if options[:key] == nil || options[:key].length < 16
|
101
|
+
raise 'grid_size must be between 4 and 9' if options[:grid_size] < 4 || options[:grid_size] > 9
|
102
|
+
raise 'invalid border size' if options[:border_size] < 0
|
103
|
+
raise 'invalid square size' if options[:square_size] < 0
|
107
104
|
|
108
105
|
hash = SipHash.digest(options[:key], title)
|
109
106
|
|
@@ -117,7 +114,7 @@ module RubyIdenticon
|
|
117
114
|
hash >>= 24
|
118
115
|
|
119
116
|
sqx = sqy = 0
|
120
|
-
|
117
|
+
(options[:grid_size] * ((options[:grid_size] + 1) / 2)).times do
|
121
118
|
if hash & 1 == 1
|
122
119
|
x = options[:border_size] + (sqx * options[:square_size])
|
123
120
|
y = options[:border_size] + (sqy * options[:square_size])
|
@@ -138,6 +135,10 @@ module RubyIdenticon
|
|
138
135
|
end
|
139
136
|
end
|
140
137
|
|
141
|
-
png.to_blob :
|
138
|
+
png.to_blob color_mode: ChunkyPNG::COLOR_INDEXED
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.create_base64(title, options = {})
|
142
|
+
Base64.encode64(self.create(title, options)).force_encoding('UTF-8')
|
142
143
|
end
|
143
144
|
end
|
data/lib/siphash.rb
CHANGED
@@ -8,10 +8,10 @@
|
|
8
8
|
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
9
|
# permit persons to whom the Software is furnished to do so, subject to
|
10
10
|
# the following conditions:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# The above copyright notice and this permission notice shall be
|
13
13
|
# included in all copies or substantial portions of the Software.
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
16
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
17
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
@@ -22,14 +22,13 @@
|
|
22
22
|
#++
|
23
23
|
|
24
24
|
module SipHash
|
25
|
-
|
26
25
|
def self.digest(key, msg)
|
27
26
|
s = State.new(key)
|
28
27
|
len = msg.size
|
29
28
|
iter = len / 8
|
30
29
|
|
31
30
|
iter.times do |i|
|
32
|
-
m = msg.slice(i * 8, 8).unpack(
|
31
|
+
m = msg.slice(i * 8, 8).unpack('Q<')[0]
|
33
32
|
s.apply_block(m)
|
34
33
|
end
|
35
34
|
|
@@ -44,7 +43,7 @@ module SipHash
|
|
44
43
|
|
45
44
|
def self.last_block(msg, len, iter)
|
46
45
|
last = (len << 56) & State::MASK_64;
|
47
|
-
|
46
|
+
|
48
47
|
r = len % 8
|
49
48
|
off = iter * 8
|
50
49
|
|
@@ -59,7 +58,7 @@ module SipHash
|
|
59
58
|
end
|
60
59
|
|
61
60
|
class State
|
62
|
-
|
61
|
+
|
63
62
|
MASK_64 = 0xffffffffffffffff
|
64
63
|
|
65
64
|
def initialize(key)
|
@@ -68,8 +67,8 @@ module SipHash
|
|
68
67
|
@v2 = 0x6c7967656e657261
|
69
68
|
@v3 = 0x7465646279746573
|
70
69
|
|
71
|
-
k0 = key.slice(0, 8).unpack(
|
72
|
-
k1 = key.slice(8, 8).unpack(
|
70
|
+
k0 = key.slice(0, 8).unpack('Q<')[0]
|
71
|
+
k1 = key.slice(8, 8).unpack('Q<')[0]
|
73
72
|
|
74
73
|
@v0 ^= k0
|
75
74
|
@v1 ^= k1
|
@@ -89,7 +88,7 @@ module SipHash
|
|
89
88
|
|
90
89
|
def compress
|
91
90
|
@v0 = (@v0 + @v1) & MASK_64
|
92
|
-
@v2 = (@v2 + @v3) & MASK_64
|
91
|
+
@v2 = (@v2 + @v3) & MASK_64
|
93
92
|
@v1 = rotl64(@v1, 13)
|
94
93
|
@v3 = rotl64(@v3, 16)
|
95
94
|
@v1 ^= @v0
|
@@ -112,6 +111,5 @@ module SipHash
|
|
112
111
|
def digest
|
113
112
|
@v0 ^ @v1 ^ @v2 ^ @v3
|
114
113
|
end
|
115
|
-
|
116
114
|
end
|
117
115
|
end
|
data/ruby_identicon.gemspec
CHANGED
@@ -31,9 +31,10 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
|
-
spec.add_development_dependency "bundler", "~> 1.
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
35
35
|
spec.add_development_dependency "rake"
|
36
|
-
spec.add_development_dependency "rspec", "~> 2.
|
36
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
37
|
+
spec.add_development_dependency "yard", "~> 0.8.7"
|
37
38
|
|
38
39
|
spec.add_dependency "chunky_png", "~> 1.3.0"
|
39
40
|
end
|
data/ruby_identicon.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "ruby_identicon.rb"
|
4
|
+
|
5
|
+
abort "Please run with a filename as an argument" unless ARGV[0]
|
6
|
+
filename = ARGV[0].clone
|
7
|
+
ARGV.clear
|
8
|
+
|
9
|
+
print "Reading standard input to generate identicon...\n"
|
10
|
+
|
11
|
+
identstring = gets
|
12
|
+
|
13
|
+
blob = RubyIdenticon.create(identstring, grid_size: 5, square_size: 70, background_color: 0xf0f0f0ff, key: "1234567890123456")
|
14
|
+
File.open(filename, "wb") do |f| f.write(blob) end
|
data/spec/ruby_identicon_spec.rb
CHANGED
@@ -2,68 +2,74 @@ require 'helper'
|
|
2
2
|
|
3
3
|
describe RubyIdenticon do
|
4
4
|
before(:each) do
|
5
|
-
Dir.mkdir(
|
5
|
+
Dir.mkdir('tmp') unless File.directory?('tmp')
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
# general parameter tests
|
9
|
+
it 'creates a binary string image blob' do
|
10
|
+
expect(RubyIdenticon.create('RubyIdenticon')).to be_a_kind_of(String)
|
10
11
|
end
|
11
12
|
|
12
|
-
it
|
13
|
-
lambda { RubyIdenticon.create(nil) }.should raise_exception(
|
13
|
+
it 'does not create a binary string image blob with an invalid title' do
|
14
|
+
lambda { RubyIdenticon.create(nil) }.should raise_exception('title cannot be nil')
|
14
15
|
end
|
15
16
|
|
16
|
-
it
|
17
|
-
lambda { RubyIdenticon.create(
|
17
|
+
it 'does not create a binary string image blob with an invalid key' do
|
18
|
+
lambda { RubyIdenticon.create('identicons are great!', key: "\x00\x11\x22\x33\x44") }.should raise_exception('key is nil or less than 16 bytes')
|
18
19
|
end
|
19
20
|
|
20
|
-
it
|
21
|
-
lambda { RubyIdenticon.create(
|
22
|
-
lambda { RubyIdenticon.create(
|
21
|
+
it 'does not create a binary string image blob with an invalid grid size' do
|
22
|
+
lambda { RubyIdenticon.create('RubyIdenticon', grid_size: 2) }.should raise_exception('grid_size must be between 4 and 9')
|
23
|
+
lambda { RubyIdenticon.create('RubyIdenticon', grid_size: 20) }.should raise_exception('grid_size must be between 4 and 9')
|
23
24
|
end
|
24
25
|
|
25
|
-
it
|
26
|
-
lambda { RubyIdenticon.create(
|
26
|
+
it 'does not create a binary string image blob with an invalid square_size size' do
|
27
|
+
lambda { RubyIdenticon.create('RubyIdenticon', square_size: -2) }.should raise_exception('invalid square size')
|
27
28
|
end
|
28
29
|
|
29
|
-
it
|
30
|
-
lambda { RubyIdenticon.create(
|
30
|
+
it 'does not create a binary string image blob with an invalid border_size size' do
|
31
|
+
lambda { RubyIdenticon.create('RubyIdenticon', border_size: -2) }.should raise_exception('invalid border size')
|
31
32
|
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
result = File.open("tmp/ruby_identicon.png", "wb") do |f| f.write(blob) end
|
34
|
+
# blob creation tests
|
35
|
+
it 'creates a png image file' do
|
36
|
+
blob = RubyIdenticon.create('RubyIdenticon')
|
37
|
+
result = File.open('tmp/ruby_identicon.png', 'wb') { |f| f.write(blob) }
|
38
38
|
expect(result).to be_true
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
42
|
-
blob = RubyIdenticon.create(
|
43
|
-
result = File.open(
|
41
|
+
it 'creates a png image file of grid size 5, square size 70 and grey background' do
|
42
|
+
blob = RubyIdenticon.create('RubyIdenticon', grid_size: 5, square_size: 70, background_color: 0xf0f0f0ff, key: '1234567890123456')
|
43
|
+
result = File.open('tmp/ruby_identicon_gs5_white.png', 'wb') { |f| f.write(blob) }
|
44
44
|
expect(result).to be_true
|
45
45
|
end
|
46
46
|
|
47
|
-
it
|
47
|
+
it 'creates 10 png image files' do
|
48
48
|
10.times do |count|
|
49
49
|
blob = RubyIdenticon.create("RubyIdenticon_#{count}")
|
50
|
-
result = File.open("tmp/ruby_identicon_#{count}.png",
|
50
|
+
result = File.open("tmp/ruby_identicon_#{count}.png", 'wb') { |f| f.write(blob) }
|
51
51
|
expect(result).to be_true
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
result = RubyIdenticon.create_and_save("RubyIdenticon is fun", "tmp/test_identicon.png")
|
55
|
+
# file creation tests
|
56
|
+
it 'creates a png image file via create_and_save' do
|
57
|
+
result = RubyIdenticon.create_and_save('RubyIdenticon is fun', 'tmp/test_identicon.png')
|
59
58
|
expect(result).to be_true
|
60
59
|
end
|
61
60
|
|
62
|
-
it
|
63
|
-
lambda { RubyIdenticon.create_and_save(
|
61
|
+
it 'does not create a png image file via create_and_save with an invalid filename' do
|
62
|
+
lambda { RubyIdenticon.create_and_save('RubyIdenticon is fun', nil) }.should raise_exception('filename cannot be nil')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'does not create a png image file via create_and_save with an invalid title' do
|
66
|
+
lambda { RubyIdenticon.create_and_save(nil, 'tmp/test_identicon.png') }.should raise_exception('title cannot be nil')
|
64
67
|
end
|
65
68
|
|
66
|
-
|
67
|
-
|
69
|
+
# Base64 creation tests
|
70
|
+
it 'creates base64 version of the image' do
|
71
|
+
blob = RubyIdenticon.create('RubyIdenticon')
|
72
|
+
base64 = RubyIdenticon.create_base64('RubyIdenticon')
|
73
|
+
expect(Base64.decode64(base64).force_encoding('UTF-8')).to eq blob
|
68
74
|
end
|
69
75
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_identicon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Branson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,28 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
47
|
+
version: '2.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2.
|
54
|
+
version: '2.14'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.8.7
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.8.7
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: chunky_png
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,6 +107,7 @@ files:
|
|
93
107
|
- lib/ruby_identicon/version.rb
|
94
108
|
- lib/siphash.rb
|
95
109
|
- ruby_identicon.gemspec
|
110
|
+
- ruby_identicon.rb
|
96
111
|
- spec/helper.rb
|
97
112
|
- spec/ruby_identicon_spec.rb
|
98
113
|
homepage: ''
|
@@ -115,10 +130,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
130
|
version: '0'
|
116
131
|
requirements: []
|
117
132
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.
|
133
|
+
rubygems_version: 2.4.3
|
119
134
|
signing_key:
|
120
135
|
specification_version: 4
|
121
136
|
summary: A Ruby Gem for creating GitHub like identicons
|
122
137
|
test_files:
|
123
138
|
- spec/helper.rb
|
124
139
|
- spec/ruby_identicon_spec.rb
|
140
|
+
has_rdoc:
|