uuidee 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uuidee.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Paul Schuegraf
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ Uuidee
2
+ ======
3
+
4
+ I could not find a pure ruby uuid gem that supported UUID v3, v4, and v5, and was bundle-friendly. Please let me know if you see one!
5
+
6
+ Pseudo-forked from https://github.com/spectra/ruby-uuid, all credit to Pablo Lorenzoni/Shyouhei Urabe.
7
+
8
+
9
+ Original README from spectra (Pablo Lorenzoni)
10
+ ----------------------------------------------
11
+
12
+ I needed a uuid generator for Ruby. There's nothing wrong with current
13
+ implementations, I just wanted a simpler one, bundled in a single file (rather
14
+ than a gem), that could comply with RFC4122.
15
+
16
+ I found this charming one using Ruby Struct by Shyouhei Urabe (aka mput),
17
+ which is not online anymore (http://raa.ruby-lang.org/project/ruby-uuid/),
18
+ unfortunately. I had it in my HD, so I decided to put it back online.
19
+
20
+ All the credit really goes to mput. I just added a method to set the version
21
+ of UUID, since that was missing in the original code. I also intend to
22
+ implement version 2, which is also missing.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,278 @@
1
+ ### http://mput.dip.jp/mput/uuid.txt
2
+
3
+ # Copyright(c) 2005 URABE, Shyouhei.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this code, to deal in the code without restriction, including without
7
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
8
+ # sublicense, and/or sell copies of the code, and to permit persons to whom the
9
+ # code is furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the code.
13
+ #
14
+ # THE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
20
+ # CODE.
21
+ #
22
+ # 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
23
+ # include the version in the raw_bytes.
24
+
25
+ require 'digest/md5'
26
+ require 'digest/sha1'
27
+ require 'tmpdir'
28
+
29
+ # Pure ruby UUID generator, which is compatible with RFC4122
30
+ UUID = Struct.new :raw_bytes
31
+
32
+ class UUID
33
+ private_class_method :new
34
+
35
+ class << self
36
+ def mask19 v, str # :nodoc
37
+ nstr = str.bytes.to_a
38
+ version = [0, 16, 32, 48, 64, 80][v]
39
+ nstr[6] &= 0b00001111
40
+ nstr[6] |= version
41
+ # nstr[7] &= 0b00001111
42
+ # nstr[7] |= 0b01010000
43
+ nstr[8] &= 0b00111111
44
+ nstr[8] |= 0b10000000
45
+ str = ''
46
+ nstr.each { |s| str << s.chr }
47
+ str
48
+ end
49
+
50
+ def mask18 v, str # :nodoc
51
+ version = [0, 16, 32, 48, 64, 80][v]
52
+ str[6] &= 0b00001111
53
+ str[6] |= version
54
+ # str[7] &= 0b00001111
55
+ # str[7] |= 0b01010000
56
+ str[8] &= 0b00111111
57
+ str[8] |= 0b10000000
58
+ str
59
+ end
60
+
61
+ def mask v, str
62
+ if RUBY_VERSION >= "1.9.0"
63
+ return mask19 v, str
64
+ else
65
+ return mask18 v, str
66
+ end
67
+ end
68
+ private :mask, :mask18, :mask19
69
+
70
+ # UUID generation using SHA1. Recommended over create_md5.
71
+ # Namespace object is another UUID, some of them are pre-defined below.
72
+ def create_sha1 str, namespace
73
+ sha1 = Digest::SHA1.new
74
+ sha1.update namespace.raw_bytes
75
+ sha1.update str
76
+ sum = sha1.digest
77
+ raw = mask 5, sum[0..15]
78
+ ret = new raw
79
+ ret.freeze
80
+ ret
81
+ end
82
+ alias :create_v5 :create_sha1
83
+
84
+ # UUID generation using MD5 (for backward compat.)
85
+ def create_md5 str, namespace
86
+ md5 = Digest::MD5.new
87
+ md5.update namespace.raw_bytes
88
+ md5.update str
89
+ sum = md5.digest
90
+ raw = mask 3, sum[0..16]
91
+ ret = new raw
92
+ ret.freeze
93
+ ret
94
+ end
95
+ alias :create_v3 :create_md5
96
+
97
+ # UUID generation using random-number generator. From it's random
98
+ # nature, there's no warranty that the created ID is really universaly
99
+ # unique.
100
+ def create_random
101
+ rnd = [
102
+ rand(0x100000000),
103
+ rand(0x100000000),
104
+ rand(0x100000000),
105
+ rand(0x100000000),
106
+ ].pack "N4"
107
+ raw = mask 4, rnd
108
+ ret = new raw
109
+ ret.freeze
110
+ ret
111
+ end
112
+ alias :create_v4 :create_random
113
+
114
+ def read_state fp # :nodoc:
115
+ fp.rewind
116
+ Marshal.load fp.read
117
+ end
118
+
119
+ def write_state fp, c, m # :nodoc:
120
+ fp.rewind
121
+ str = Marshal.dump [c, m]
122
+ fp.write str
123
+ end
124
+
125
+ private :read_state, :write_state
126
+ STATE_FILE = 'ruby-uuid'
127
+
128
+ # create the "version 1" UUID with current system clock, current UTC
129
+ # timestamp, and the IEEE 802 address (so-called MAC address).
130
+ #
131
+ # Speed notice: it's slow. It writes some data into hard drive on every
132
+ # invokation. If you want to speed this up, try remounting tmpdir with a
133
+ # memory based filesystem (such as tmpfs). STILL slow? then no way but
134
+ # rewrite it with c :)
135
+ def create clock=nil, time=nil, mac_addr=nil
136
+ c = t = m = nil
137
+ Dir.chdir Dir.tmpdir do
138
+ unless FileTest.exist? STATE_FILE then
139
+ # Generate a pseudo MAC address because we have no pure-ruby way
140
+ # to know the MAC address of the NIC this system uses. Note
141
+ # that cheating with pseudo arresses here is completely legal:
142
+ # see Section 4.5 of RFC4122 for details.
143
+ sha1 = Digest::SHA1.new
144
+ 256.times do
145
+ r = [rand(0x100000000)].pack "N"
146
+ sha1.update r
147
+ end
148
+ str = sha1.digest
149
+ r = rand 14 # 20-6
150
+ node = str[r, 6] || str
151
+ if RUBY_VERSION >= "1.9.0"
152
+ nnode = node.bytes.to_a
153
+ nnode[0] |= 0x01
154
+ node = ''
155
+ nnode.each { |s| node << s.chr }
156
+ else
157
+ node[0] |= 0x01 # multicast bit
158
+ end
159
+ k = rand 0x40000
160
+ open STATE_FILE, 'w' do |fp|
161
+ fp.flock IO::LOCK_EX
162
+ write_state fp, k, node
163
+ fp.chmod 0o777 # must be world writable
164
+ end
165
+ end
166
+ open STATE_FILE, 'r+' do |fp|
167
+ fp.flock IO::LOCK_EX
168
+ c, m = read_state fp
169
+ c = clock % 0x4000 if clock
170
+ m = mac_addr if mac_addr
171
+ t = time
172
+ if t.nil? then
173
+ # UUID epoch is 1582/Oct/15
174
+ tt = Time.now
175
+ t = tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
176
+ end
177
+ c = c.succ # important; increment here
178
+ write_state fp, c, m
179
+ end
180
+ end
181
+
182
+ tl = t & 0xFFFF_FFFF
183
+ tm = t >> 32
184
+ tm = tm & 0xFFFF
185
+ th = t >> 48
186
+ th = th & 0x0FFF
187
+ th = th | 0x1000
188
+ cl = c & 0xFF
189
+ ch = c & 0x3F00
190
+ ch = ch >> 8
191
+ ch = ch | 0x80
192
+ pack tl, tm, th, cl, ch, m
193
+ end
194
+ alias :create_v1 :create
195
+
196
+ # A simple GUID parser: just ignores unknown characters and convert
197
+ # hexadecimal dump into 16-octet object.
198
+ def parse obj
199
+ str = obj.to_s.sub %r/\Aurn:uuid:/, ''
200
+ str.gsub! %r/[^0-9A-Fa-f]/, ''
201
+ raw = str[0..31].lines.to_a.pack 'H*'
202
+ ret = new raw
203
+ ret.freeze
204
+ ret
205
+ end
206
+
207
+ # The 'primitive constructor' of this class
208
+ # Note UUID.pack(uuid.unpack) == uuid
209
+ def pack tl, tm, th, ch, cl, n
210
+ raw = [tl, tm, th, ch, cl, n].pack "NnnCCa6"
211
+ ret = new raw
212
+ ret.freeze
213
+ ret
214
+ end
215
+ end
216
+
217
+ # The 'primitive deconstructor', or the dual to pack.
218
+ # Note UUID.pack(uuid.unpack) == uuid
219
+ def unpack
220
+ raw_bytes.unpack "NnnCCa6"
221
+ end
222
+
223
+ # Generate the string representation (a.k.a GUID) of this UUID
224
+ def to_s
225
+ a = unpack
226
+ tmp = a[-1].unpack 'C*'
227
+ a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
228
+ "%08x-%04x-%04x-%02x%02x-%s" % a
229
+ end
230
+ alias guid to_s
231
+
232
+ # Convert into a RFC4122-comforming URN representation
233
+ def to_uri
234
+ "urn:uuid:" + self.to_s
235
+ end
236
+ alias urn to_uri
237
+
238
+ # Convert into 128-bit unsigned integer
239
+ # Typically a Bignum instance, but can be a Fixnum.
240
+ def to_int
241
+ tmp = self.raw_bytes.unpack "C*"
242
+ tmp.inject do |r, i|
243
+ r * 256 | i
244
+ end
245
+ end
246
+ alias to_i to_int
247
+
248
+ # Gets the version of this UUID
249
+ # returns nil if bad version
250
+ def version
251
+ a = unpack
252
+ v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
253
+ return v if (1..5).include? v
254
+ return nil
255
+ end
256
+
257
+ # Two UUIDs are said to be equal if and only if their (byte-order
258
+ # canonicalized) integer representations are equivallent. Refer RFC4122 for
259
+ # details.
260
+ def == other
261
+ to_i == other.to_i
262
+ end
263
+
264
+ include Comparable
265
+ # UUIDs are comparable (don't know what benefits are there, though).
266
+ def <=> other
267
+ to_s <=> other.to_s
268
+ end
269
+
270
+ # Pre-defined UUID Namespaces described in RFC4122 Appendix C.
271
+ NameSpace_DNS = parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
272
+ NameSpace_URL = parse "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
273
+ NameSpace_OID = parse "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
274
+ NameSpace_X500 = parse "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
275
+
276
+ # The Nil UUID in RFC4122 Section 4.1.7
277
+ Nil = parse "00000000-0000-0000-0000-000000000000"
278
+ end
@@ -0,0 +1,2 @@
1
+ require "uuidee/version"
2
+ require 'uuid'
@@ -0,0 +1,3 @@
1
+ module Uuidee
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,91 @@
1
+ require 'test/unit'
2
+ require 'uuid'
3
+
4
+ class TC_UUID < Test::Unit::TestCase
5
+ def test_v1
6
+ u1 = UUID.create
7
+ u2 = UUID.create
8
+ assert_not_equal u1, u2
9
+ end
10
+
11
+ def test_v1_repeatability
12
+ u1 = UUID.create 1, 2, "345678"
13
+ u2 = UUID.create 1, 2, "345678"
14
+ assert_equal u1, u2
15
+ end
16
+
17
+ def test_v3
18
+ u1 = UUID.create_md5 "foo", UUID::NameSpace_DNS
19
+ u2 = UUID.create_md5 "foo", UUID::NameSpace_DNS
20
+ u3 = UUID.create_md5 "foo", UUID::NameSpace_URL
21
+ assert_equal u1, u2
22
+ assert_not_equal u1, u3
23
+ end
24
+
25
+ def test_v5
26
+ u1 = UUID.create_sha1 "foo", UUID::NameSpace_DNS
27
+ u2 = UUID.create_sha1 "foo", UUID::NameSpace_DNS
28
+ u3 = UUID.create_sha1 "foo", UUID::NameSpace_URL
29
+ assert_equal u1, u2
30
+ assert_not_equal u1, u3
31
+ end
32
+
33
+ def test_v4
34
+ # This test is not perfect, because the random nature of version 4
35
+ # UUID it is not always true that the three objects below really
36
+ # differ. But in real life it's enough to say we're OK when this
37
+ # passes.
38
+ u1 = UUID.create_random
39
+ u2 = UUID.create_random
40
+ u3 = UUID.create_random
41
+ assert_not_equal u1.raw_bytes, u2.raw_bytes
42
+ assert_not_equal u1.raw_bytes, u3.raw_bytes
43
+ assert_not_equal u2.raw_bytes, u3.raw_bytes
44
+ end
45
+
46
+ def test_pack
47
+ u1 = UUID.pack 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4,
48
+ "\000\300O\3240\310"
49
+ assert_equal UUID::NameSpace_DNS, u1
50
+ end
51
+
52
+ def test_unpack
53
+ tl, tm, th, cl, ch, m = UUID::NameSpace_DNS.unpack
54
+ assert_equal 0x6ba7b810, tl
55
+ assert_equal 0x9dad, tm
56
+ assert_equal 0x11d1, th
57
+ assert_equal 0x80, cl
58
+ assert_equal 0xb4, ch
59
+ assert_equal "\000\300O\3240\310", m
60
+ end
61
+
62
+ def test_parse
63
+ u1 = UUID.pack 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4,
64
+ "\000\300O\3240\310"
65
+ u2 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
66
+ u3 = UUID.parse "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
67
+ assert_equal u1, u2
68
+ assert_equal u1, u3
69
+ end
70
+
71
+ def test_to_s
72
+ u1 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
73
+ assert_equal "6ba7b810-9dad-11d1-80b4-00c04fd430c8", u1.to_s
74
+ end
75
+
76
+ def test_to_i
77
+ u1 = UUID.parse "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
78
+ assert_equal 0x6ba7b8109dad11d180b400c04fd430c8, u1.to_i
79
+ end
80
+
81
+ def test_version
82
+ u1 = UUID.create_v1
83
+ assert_equal 1, u1.version
84
+ u3 = UUID.create_v3 "foo", UUID::NameSpace_DNS
85
+ assert_equal 3, u3.version
86
+ u4 = UUID.create_v4
87
+ assert_equal 4, u4.version
88
+ u5 = UUID.create_v5 "foo", UUID::NameSpace_DNS
89
+ assert_equal 5, u5.version
90
+ end
91
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'uuidee/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "uuidee"
8
+ gem.version = Uuidee::VERSION
9
+ gem.authors = ["Paul Schuegraf, Pablo Lorenzoni, Shyouhei Urabe"]
10
+ gem.email = ["paul@verticallabs.ca"]
11
+ gem.description = %q{Bundle friendly pure ruby UUID generator supporting v1, v3, v4, v5}
12
+ gem.summary = %q{Bundle friendly pure ruby UUID generator supporting v1, v3, v4, v5}
13
+ gem.homepage = "https://github.com/verticallabs/uuidee.git"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency 'test-unit'
21
+ gem.add_development_dependency 'debugger'
22
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uuidee
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Schuegraf, Pablo Lorenzoni, Shyouhei Urabe
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: test-unit
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: debugger
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Bundle friendly pure ruby UUID generator supporting v1, v3, v4, v5
47
+ email:
48
+ - paul@verticallabs.ca
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - lib/uuid.rb
59
+ - lib/uuidee.rb
60
+ - lib/uuidee/version.rb
61
+ - test/uuidee_test.rb
62
+ - uuidee.gemspec
63
+ homepage: https://github.com/verticallabs/uuidee.git
64
+ licenses: []
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ! '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.24
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Bundle friendly pure ruby UUID generator supporting v1, v3, v4, v5
87
+ test_files:
88
+ - test/uuidee_test.rb
89
+ has_rdoc: