uuidee 0.0.1

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