ruby_identicon 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|