better-uuid 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bf1e28e13ece5b54517f75f4dbeb57ae5fb5b9c7
4
+ data.tar.gz: 6336da4021c61f05105ddf3c4cfacef1f9f99d7d
5
+ SHA512:
6
+ metadata.gz: 65c53c292aca251a8f4fb60802aa608c42907b03a1a54b05e78e1cef847ba1996103e9fe9ff510133f11659fda105ada419227e8e1117dfd79a092fe8a2a433a
7
+ data.tar.gz: c7a421d5f807749c855ae3c37a3d67ac4d3c97688655ba3a38a2c0c3fc6823bb26fc0160732e45e60bec82bf047baccc6e42aeadef326a90286b36406e2f9599
checksums.yaml.gz.sig ADDED
Binary file
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ �j�b�]�AY�*�����u�N��7, �ཫ 4~�Xb:,�dߴeF5�Vir�A5u�k��H�����9�SX�p_<���]����;��}���A[���Z�S�������`ry�/��=wɯ<�ofG�C4���W��':�(��u�68��g�*;Z��-E�qt�.0�0g�i|�3�uz,r����u�S�:c��ͼ��bg�W�lybVu.�f|)Z(��������5;5|��;,��'N)���U`�š�q�
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --warnings
3
+ --require spec_helper
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Barry Allard
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ 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 Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ [![Build Status](https://travis-ci.org/steakknife/better-uuid.svg)](https://travis-ci.org/steakknife/better-uuid)
2
+
3
+ # BetterUUID
4
+
5
+ ## Advantages
6
+
7
+ - Very fast because it doesn't hit disk on every create, updates in a seperate thread
8
+
9
+
10
+ ## Usage
11
+
12
+ BetterUUID.create # or create_v1
13
+ BetterUUID.create_v3 'key', BetterUUID::Namespace::DNS # or URL, OID or X500
14
+ BetterUUID.create_v4 # random
15
+ BetterUUID.create_v5 'key', BetterUUID::Namespace::DNS # or URL, OID or X500
16
+
17
+ BetterUUID.parse 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8'
18
+
19
+ ## Installation
20
+
21
+ ### Bundler
22
+
23
+ gem 'better-uuid'
24
+
25
+ ### manually
26
+
27
+ gem cert --add <(curl -L https://raw.githubusercontent.com/steakknife/better-uuid/master/gem-public_cert.pem)
28
+ gem install better-uuid -P HighSecurity
29
+
30
+ ## Author
31
+
32
+ Barry Allard
33
+
34
+ ## Attribution
35
+
36
+ Heavily based off https://github.com/spectra/ruby-uuid
37
+ which was based on http://mput.dip.jp/mput/uuid.txt
38
+
39
+ ## License
40
+
41
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ fail 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'BetterUUID'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
18
+
19
+ desc 'Run RSpec specs'
20
+ task :spec do
21
+ ARGV.delete 'spec'
22
+ sh "bundle exec rspec #{ARGV.join ' '}"
23
+ end
24
+
25
+ desc 'Benchmark'
26
+ task :benchmark do
27
+ sh "bundle exec ruby lib/benchmark.rb"
28
+ end
29
+
30
+ task default: :spec
data/lib/benchmark.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'better-uuid'
2
+ begin
3
+ require 'absolute_time'
4
+ rescue LoadError
5
+ require 'benchmark'
6
+ end
7
+ NUM_OPS = 1_000_000
8
+
9
+ FOO = 'foo'
10
+
11
+ def time(&block)
12
+ (defined?(AbsoluteTime) ? AbsoluteTime : Benchmark).realtime(&block)
13
+ end
14
+
15
+ # v1
16
+ seconds = time { NUM_OPS.times { BetterUUID.create_v1 } }
17
+ puts "#{NUM_OPS / seconds} create_v1/sec (#{1e6*seconds / NUM_OPS} usec/op)"
18
+
19
+ # v3
20
+ seconds = time { NUM_OPS.times { BetterUUID.create_v3 FOO, BetterUUID::Namespace::URL } }
21
+ puts "#{NUM_OPS / seconds} create_v3/sec (#{1e6*seconds / NUM_OPS} usec/op)"
22
+
23
+ # v4
24
+ seconds = time { NUM_OPS.times { BetterUUID.create_v4 } }
25
+ puts "#{NUM_OPS / seconds} create_v4/sec (#{1e6*seconds / NUM_OPS} usec/op)"
26
+
27
+ # v5
28
+ seconds = time { NUM_OPS.times { BetterUUID.create_v5 FOO, BetterUUID::Namespace::URL } }
29
+ puts "#{NUM_OPS / seconds} create_v5/sec (#{1e6*seconds / NUM_OPS} usec/op)"
@@ -0,0 +1,28 @@
1
+ ### https://raw.githubusercontent.com/spectra/ruby-uuid/master/uuid.rb
2
+ ### original http://mput.dip.jp/mput/uuid.txt
3
+
4
+ # Copyright(c) 2005 URABE, Shyouhei.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this code, to deal in the code without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the code, and to permit persons to whom the
10
+ # code is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the code.
14
+ #
15
+ # THE CODE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
21
+ # CODE.
22
+ #
23
+ # 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
24
+ # include the version in the raw_bytes.
25
+
26
+ require 'better-uuid/class'
27
+ require 'better-uuid/namespace'
28
+ require 'better-uuid/nil'
@@ -0,0 +1,9 @@
1
+ require 'better-uuid/versions'
2
+ require 'better-uuid/class_methods'
3
+ require 'better-uuid/instance_methods'
4
+
5
+ class BetterUUID
6
+ private_class_method :new
7
+ extend BetterUUID::ClassMethods
8
+ include BetterUUID::InstanceMethods
9
+ end
@@ -0,0 +1,167 @@
1
+ ### https://raw.githubusercontent.com/spectra/ruby-uuid/master/uuid.rb
2
+ ### original http://mput.dip.jp/mput/uuid.txt
3
+
4
+ # Copyright(c) 2005 URABE, Shyouhei.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this code, to deal in the code without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the code, and to permit persons to whom the
10
+ # code is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the code.
14
+ #
15
+ # THE CODE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
21
+ # CODE.
22
+ #
23
+ # 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
24
+ # include the version in the raw_bytes.
25
+
26
+ require 'better-uuid/state_file'
27
+
28
+ require 'digest/md5'
29
+ require 'digest/sha1'
30
+
31
+
32
+ # Pure ruby UUID generator, which is compatible with RFC4122
33
+
34
+ class BetterUUID
35
+
36
+ module ClassMethods
37
+ def mask19(v, str) # :nodoc
38
+ nstr = str.bytes.to_a
39
+ version = [0, 16, 32, 48, 64, 80][v]
40
+ nstr[6] &= 0b00001111
41
+ nstr[6] |= version
42
+ # nstr[7] &= 0b00001111
43
+ # nstr[7] |= 0b01010000
44
+ nstr[8] &= 0b00111111
45
+ nstr[8] |= 0b10000000
46
+ str = ''
47
+ nstr.each { |s| str << s.chr }
48
+ str
49
+ end
50
+
51
+ def mask18(v, str) # :nodoc
52
+ version = [0, 16, 32, 48, 64, 80][v]
53
+ str[6] &= 0b00001111
54
+ str[6] |= version
55
+ # str[7] &= 0b00001111
56
+ # str[7] |= 0b01010000
57
+ str[8] &= 0b00111111
58
+ str[8] |= 0b10000000
59
+ str
60
+ end
61
+
62
+ def mask(v, str)
63
+ if RUBY_VERSION >= '1.9.0'
64
+ return mask19 v, str
65
+ else
66
+ return mask18 v, str
67
+ end
68
+ end
69
+ private :mask, :mask18, :mask19
70
+
71
+ # UUID generation using SHA1. Recommended over create_md5.
72
+ # Namespace object is another UUID, some of them are pre-defined below.
73
+ def create_sha1(str, namespace)
74
+ sha1 = Digest::SHA1.new
75
+ sha1.update namespace.raw_bytes
76
+ sha1.update str
77
+ sum = sha1.digest
78
+ raw = mask 5, sum[0..15]
79
+ ret = new raw
80
+ ret.freeze
81
+ ret
82
+ end
83
+ alias :create_v5 :create_sha1
84
+
85
+ # UUID generation using MD5 (for backward compat.)
86
+ def create_md5(str, namespace)
87
+ md5 = Digest::MD5.new
88
+ md5.update namespace.raw_bytes
89
+ md5.update str
90
+ sum = md5.digest
91
+ raw = mask 3, sum[0..16]
92
+ ret = new raw
93
+ ret.freeze
94
+ ret
95
+ end
96
+ alias :create_v3 :create_md5
97
+
98
+ # UUID generation using random-number generator. From it's random
99
+ # nature, there's no warranty that the created ID is really universaly
100
+ # unique.
101
+ def create_random
102
+ rnd = [
103
+ rand(0x100000000),
104
+ rand(0x100000000),
105
+ rand(0x100000000),
106
+ rand(0x100000000),
107
+ ].pack 'N4'
108
+ raw = mask 4, rnd
109
+ ret = new raw
110
+ ret.freeze
111
+ ret
112
+ end
113
+ alias :create_v4 :create_random
114
+
115
+ def get_time
116
+ # UUID epoch is 1582/Oct/15
117
+ tt = Time.now
118
+ tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
119
+ end
120
+ private :get_time
121
+
122
+ # create the 'version 1' UUID with current system clock, current UTC
123
+ # timestamp, and the IEEE 802 address (so-called MAC address).
124
+ #
125
+ # Speed notice: it's slow. It writes some data into hard drive on every
126
+ # invokation. If you want to speed this up, try remounting tmpdir with a
127
+ # memory based filesystem (such as tmpfs). STILL slow? then no way but
128
+ # rewrite it with c :)
129
+ def create(clock = nil, time = nil, mac_addr = nil)
130
+ c, m = StateFile::update(clock, mac_addr)
131
+ time ||= get_time
132
+
133
+ tl = time & 0xFFFF_FFFF
134
+ tm = time >> 32
135
+ tm = tm & 0xFFFF
136
+ th = time >> 48
137
+ th = th & 0x0FFF
138
+ th = th | 0x1000
139
+ cl = c & 0xFF
140
+ ch = c & 0x3F00
141
+ ch = ch >> 8
142
+ ch = ch | 0x80
143
+ pack tl, tm, th, cl, ch, m
144
+ end
145
+ alias :create_v1 :create
146
+
147
+ # A simple GUID parser: just ignores unknown characters and convert
148
+ # hexadecimal dump into 16-octet object.
149
+ def parse(obj)
150
+ str = obj.to_s.sub %r/\Aurn:uuid:/, ''
151
+ str.gsub! %r/[^0-9A-Fa-f]/, ''
152
+ raw = str[0..31].lines.to_a.pack 'H*'
153
+ ret = new raw
154
+ ret.freeze
155
+ ret
156
+ end
157
+
158
+ # The 'primitive constructor' of this class
159
+ # Note UUID.pack(uuid.unpack) == uuid
160
+ def pack(tl, tm, th, ch, cl, n)
161
+ raw = [tl, tm, th, ch, cl, n].pack 'NnnCCa6'
162
+ ret = new raw
163
+ ret.freeze
164
+ ret
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,85 @@
1
+ ### https://raw.githubusercontent.com/spectra/ruby-uuid/master/uuid.rb
2
+ ### original http://mput.dip.jp/mput/uuid.txt
3
+
4
+ # Copyright(c) 2005 URABE, Shyouhei.
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this code, to deal in the code without restriction, including without
8
+ # limitation the rights to use, copy, modify, merge, publish, distribute,
9
+ # sublicense, and/or sell copies of the code, and to permit persons to whom the
10
+ # code is furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the code.
14
+ #
15
+ # THE CODE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE CODE OR THE USE OR OTHER DEALINGS IN THE
21
+ # CODE.
22
+ #
23
+ # 2009-02-20: Modified by Pablo Lorenzoni <pablo@propus.com.br> to correctly
24
+ # include the version in the raw_bytes.
25
+
26
+
27
+ # Pure ruby UUID generator, which is compatible with RFC4122
28
+
29
+ class BetterUUID
30
+ module InstanceMethods
31
+
32
+ # The 'primitive deconstructor', or the dual to pack.
33
+ # Note UUID.pack(uuid.unpack) == uuid
34
+ def unpack
35
+ raw_bytes.unpack 'NnnCCa6'
36
+ end
37
+
38
+ # Generate the string representation (a.k.a GUID) of this UUID
39
+ def to_s
40
+ a = unpack
41
+ tmp = a[-1].unpack 'C*'
42
+ a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
43
+ '%08x-%04x-%04x-%02x%02x-%s' % a
44
+ end
45
+ alias guid to_s
46
+
47
+ # Convert into a RFC4122-comforming URN representation
48
+ def to_uri
49
+ 'urn:uuid:' + self.to_s
50
+ end
51
+ alias urn to_uri
52
+
53
+ # Convert into 128-bit unsigned integer
54
+ # Typically a Bignum instance, but can be a Fixnum.
55
+ def to_int
56
+ tmp = self.raw_bytes.unpack 'C*'
57
+ tmp.inject do |r, i|
58
+ r * 256 | i
59
+ end
60
+ end
61
+ alias to_i to_int
62
+
63
+ # Gets the version of this UUID
64
+ # returns nil if bad version
65
+ def version
66
+ a = unpack
67
+ v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
68
+ return v if (1..5).include? v
69
+ return nil
70
+ end
71
+
72
+ # Two UUIDs are said to be equal if and only if their (byte-order
73
+ # canonicalized) integer representations are equivallent. Refer RFC4122 for
74
+ # details.
75
+ def ==(other)
76
+ to_i == other.to_i
77
+ end
78
+
79
+ include Comparable
80
+ # UUIDs are comparable (don't know what benefits are there, though).
81
+ def <=>(other)
82
+ to_s <=> other.to_s
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,9 @@
1
+ class BetterUUID
2
+ # Pre-defined UUID Namespaces described in RFC4122 Appendix C.
3
+ module Namespace
4
+ DNS = BetterUUID.parse '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
5
+ URL = BetterUUID.parse '6ba7b811-9dad-11d1-80b4-00c04fd430c8'
6
+ OID = BetterUUID.parse '6ba7b812-9dad-11d1-80b4-00c04fd430c8'
7
+ X500 = BetterUUID.parse '6ba7b814-9dad-11d1-80b4-00c04fd430c8'
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ class BetterUUID
2
+ Nil = parse '00000000-0000-0000-0000-000000000000'
3
+ end
@@ -0,0 +1,111 @@
1
+ require 'digest/sha1'
2
+ require 'tmpdir'
3
+
4
+ # Pure ruby UUID generator, which is compatible with RFC4122
5
+
6
+ class BetterUUID
7
+ module StateFile
8
+ extend self
9
+
10
+ FILENAME = 'better-uuid.ruby.marshall'
11
+
12
+ def update(clock = nil, mac_addr = nil)
13
+ result = change_state(clock, mac_addr)
14
+ start_background_writer
15
+ result
16
+ end
17
+
18
+ private
19
+ def start_background_writer
20
+ $_better_uuid_background_writer ||= Thread.new { background_writer }
21
+ end
22
+
23
+ def background_write
24
+ if $_better_uuid_background_writer_state_dirty
25
+ open(filename, 'wb') { |fp|
26
+ fp.flock IO::LOCK_EX
27
+ write fp
28
+ }
29
+ $_better_uuid_background_writer_state_dirty = false
30
+ end
31
+ rescue Errno::EACCES, Errno::ENOENT, Errno::ENOSPC
32
+ end
33
+
34
+ def background_writer
35
+ $_better_uuid_background_writer_state_dirty ||= false
36
+ at_exit { background_write }
37
+ loop do
38
+ background_write
39
+ sleep 3
40
+ end
41
+ end
42
+
43
+ def pseudo_mac
44
+ # Generate a pseudo MAC address because we have no pure-ruby way
45
+ # to know the MAC address of the NIC this system uses. Note
46
+ # that cheating with pseudo arresses here is completely legal:
47
+ # see Section 4.5 of RFC4122 for details.
48
+ sha1 = Digest::SHA1.new
49
+ 256.times do
50
+ r = [rand(0x100000000)].pack 'N'
51
+ sha1.update r
52
+ end
53
+ str = sha1.digest
54
+ r = rand 14 # 20-6
55
+ node = str[r, 6] || str
56
+ if RUBY_VERSION >= '1.9.0'
57
+ nnode = node.bytes.to_a
58
+ nnode[0] |= 0x01
59
+ node = ''
60
+ nnode.each { |s| node << s.chr }
61
+ else
62
+ node[0] |= 0x01 # multicast bit
63
+ end
64
+ node
65
+ end
66
+
67
+ def default_initial_state
68
+ [ rand(0x40000), pseudo_mac ]
69
+ end
70
+
71
+ def initial_state
72
+ begin
73
+ open(filename, 'rb') { |fp|
74
+ fp.flock IO::LOCK_EX
75
+ read fp
76
+ }
77
+ rescue Errno::EACCES, Errno::ENOENT, ArgumentError
78
+ default_initial_state
79
+ end
80
+ end
81
+
82
+ def next_state(clock = nil, mac_addr = nil)
83
+ $_better_uuid_background_writer_state_dirty = true
84
+ c = clock ? (clock % 0x4000) : @c
85
+ m = mac_addr ? mac_addr : @m
86
+ c = c.succ
87
+ [ c, m ]
88
+ end
89
+
90
+ def change_state(clock, mac_addr)
91
+ @c, @m = if instance_variable_defined?(:@_better_uuid_initialized)
92
+ next_state(clock, mac_addr)
93
+ else
94
+ @_better_uuid_initialized = true
95
+ initial_state
96
+ end
97
+ end
98
+
99
+ def read(fp) # :nodoc:
100
+ Marshal.load fp.read
101
+ end
102
+
103
+ def filename
104
+ File.join(Dir.tmpdir, FILENAME)
105
+ end
106
+
107
+ def write(fp) # :nodoc:
108
+ fp.write Marshal.dump([@c, @m])
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,2 @@
1
+ # Pure ruby UUID generator, which is compatible with RFC4122
2
+ BetterUUID = Struct.new :raw_bytes
@@ -0,0 +1,5 @@
1
+ require 'better-uuid/struct'
2
+
3
+ class BetterUUID
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,8 @@
1
+ require 'better-uuid/struct'
2
+
3
+ class BetterUUID
4
+ VERSION1 = :v1
5
+ VERSION3 = :v3
6
+ VERSION4 = :v4
7
+ VERSION5 = :v5
8
+ end
@@ -0,0 +1,172 @@
1
+ require 'better-uuid'
2
+
3
+ describe BetterUUID do
4
+ context 'v1' do
5
+ describe '#version' do
6
+ it { u = BetterUUID.create_v1
7
+ expect(u.version).to be(1) }
8
+ end
9
+
10
+ describe '.create' do
11
+ context 'unique' do
12
+ it { u1 = BetterUUID.create
13
+ u2 = BetterUUID.create
14
+ expect(u1).not_to eq(u2) }
15
+ end
16
+
17
+ context 'repeatable' do
18
+ it { u1 = BetterUUID.create 1, 2, '345678'
19
+ u2 = BetterUUID.create 1, 2, '345678'
20
+ expect(u1).to eq(u2) }
21
+ end
22
+ end
23
+
24
+ describe '.create_v1' do
25
+ context 'same as .create' do
26
+ it { u1 = BetterUUID.create 1, 2, '345678'
27
+ u2 = BetterUUID.create_v1 1, 2, '345678'
28
+ expect(u1).to eq(u2) }
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'v3' do
34
+ describe '#version' do
35
+ it { u = BetterUUID.create_md5 'foo', BetterUUID::Namespace::DNS
36
+ expect(u.version).to be(3) }
37
+ end
38
+
39
+ describe '.create_md5' do
40
+ context 'unique' do
41
+ it { u1 = BetterUUID.create_md5 'foo', BetterUUID::Namespace::DNS
42
+ u2 = BetterUUID.create_md5 'foo', BetterUUID::Namespace::URL
43
+ u3 = BetterUUID.create_md5 'bar', BetterUUID::Namespace::DNS
44
+ expect(u1).not_to eq(u2)
45
+ expect(u1).not_to eq(u3) }
46
+ end
47
+
48
+ context 'repeatable' do
49
+ it { u1 = BetterUUID.create_md5 'foo', BetterUUID::Namespace::DNS
50
+ u2 = BetterUUID.create_md5 'foo', BetterUUID::Namespace::DNS
51
+ expect(u1).to eq(u2) }
52
+ end
53
+ end
54
+ end
55
+
56
+ context 'v4' do
57
+ describe '#version' do
58
+ it { u = BetterUUID.create_random
59
+ expect(u.version).to be(4) }
60
+ end
61
+
62
+ describe '.create_random' do
63
+ context 'unique' do
64
+ # This test is not perfect, because the random nature of version 4
65
+ # BetterUUID it is not always true that the three objects below really
66
+ # differ. But in real life it's enough to say we're OK when this
67
+ # passes.
68
+ it { u1 = BetterUUID.create_random
69
+ u2 = BetterUUID.create_random
70
+ u3 = BetterUUID.create_random
71
+ expect(u1).not_to eq(u2)
72
+ expect(u1).not_to eq(u3) }
73
+ end
74
+ end
75
+
76
+ describe '.create_v4' do
77
+ context 'same as .create_random' do
78
+ it { expect(BetterUUID.create_random.version).to eq(BetterUUID.create_v4.version) }
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'v5' do
84
+ describe '#version' do
85
+ it { u = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::DNS
86
+ expect(u.version).to be(5) }
87
+ end
88
+
89
+ describe '.create_sha1' do
90
+ context 'repeatable' do
91
+ it { u1 = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::DNS
92
+ u2 = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::DNS
93
+ expect(u1).to eq(u2) }
94
+ end
95
+
96
+ context 'unique' do
97
+ it { u1 = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::DNS
98
+ u2 = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::URL
99
+ u3 = BetterUUID.create_sha1 'bar', BetterUUID::Namespace::DNS
100
+ expect(u1).not_to eq(u2)
101
+ expect(u1).not_to eq(u3) }
102
+ end
103
+ end
104
+
105
+ describe '.create_v5' do
106
+ context 'same as .create_sha1' do
107
+ it { u1 = BetterUUID.create_sha1 'foo', BetterUUID::Namespace::DNS
108
+ u2 = BetterUUID.create_v5 'foo', BetterUUID::Namespace::DNS
109
+ expect(u1).to eq(u2) }
110
+ end
111
+ end
112
+ end
113
+
114
+ describe '.pack' do
115
+ it { u = BetterUUID.pack(0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, "\000\300O\3240\310")
116
+ expect(u).to eq(BetterUUID::Namespace::DNS) }
117
+ end
118
+
119
+ describe '.unpack' do
120
+ it { tl, tm, th, cl, ch, m = BetterUUID::Namespace::DNS.unpack
121
+ expect(tl).to eq(0x6ba7b810)
122
+ expect(tm).to eq(0x9dad)
123
+ expect(th).to eq(0x11d1)
124
+ expect(cl).to eq(0x80)
125
+ expect(ch).to eq(0xb4)
126
+ expect(m).to eq("\000\300O\3240\310".force_encoding('ASCII-8BIT')) }
127
+ end
128
+
129
+ describe '.parse' do
130
+ it { u1 = BetterUUID.pack 0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, "\000\300O\3240\310"
131
+ u2 = BetterUUID.parse '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
132
+ u3 = BetterUUID.parse 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8'
133
+ expect(u1).to eq(u2)
134
+ expect(u1).to eq(u3) }
135
+ end
136
+
137
+ describe '.to_s' do
138
+ it { s = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
139
+ u = BetterUUID.parse(s)
140
+ expect(u.to_s).to eq(s) }
141
+ end
142
+
143
+ describe '.guid' do
144
+ context 'same as .to_s' do
145
+ it { u = BetterUUID.create
146
+ expect(u.guid).to eq(u.to_s) }
147
+ end
148
+ end
149
+
150
+ describe '.to_uri' do
151
+ context 'works' do
152
+ it { s = 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8'
153
+ u = BetterUUID.parse s
154
+ expect(u.to_uri).to eq(s) }
155
+ end
156
+
157
+ context 'same as .urn' do
158
+ it { s = 'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8'
159
+ u = BetterUUID.parse s
160
+ expect(u.urn).to eq(u.to_uri) }
161
+ end
162
+ end
163
+
164
+ describe '.to_i' do
165
+ it { s = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
166
+ u = BetterUUID.parse(s)
167
+ i = 0x6ba7b8109dad11d180b400c04fd430c8
168
+ expect(u.to_i).to eq(i) }
169
+ end
170
+ end
171
+
172
+
@@ -0,0 +1,82 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
4
+ # file to always be loaded, without a need to explicitly require it in any files.
5
+ #
6
+ # Given that it is always loaded, you are encouraged to keep this file as
7
+ # light-weight as possible. Requiring heavyweight dependencies from this file
8
+ # (such as loading up an entire rails app) will add to the boot time of your
9
+ # test suite on EVERY test run, even for an individual file that may not need
10
+ # all of that loaded.
11
+ #
12
+ # The `.rspec` file also contains a few flags that are not defaults but that
13
+ # users commonly want.
14
+ #
15
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+ RSpec.configure do |config|
17
+ # The settings below are suggested to provide a good initial experience
18
+ # with RSpec, but feel free to customize to your heart's content.
19
+ =begin
20
+ # These two settings work together to allow you to limit a spec run
21
+ # to individual examples or groups you care about by tagging them with
22
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
23
+ # get run.
24
+ config.filter_run :focus
25
+ config.run_all_when_everything_filtered = true
26
+
27
+ # Many RSpec users commonly either run the entire suite or an individual
28
+ # file, and it's useful to allow more verbose output when running an
29
+ # individual spec file.
30
+ if config.files_to_run.one?
31
+ # RSpec filters the backtrace by default so as not to be so noisy.
32
+ # This causes the full backtrace to be printed when running a single
33
+ # spec file (e.g. to troubleshoot a particular spec failure).
34
+ config.full_backtrace = true
35
+
36
+ # Use the documentation formatter for detailed output,
37
+ # unless a formatter has already been configured
38
+ # (e.g. via a command-line flag).
39
+ config.formatter = 'doc' if config.formatters.none?
40
+ end
41
+
42
+ # Print the 10 slowest examples and example groups at the
43
+ # end of the spec run, to help surface which specs are running
44
+ # particularly slow.
45
+ config.profile_examples = 10
46
+
47
+ # Run specs in random order to surface order dependencies. If you find an
48
+ # order dependency and want to debug it, you can fix the order by providing
49
+ # the seed, which is printed after each run.
50
+ # --seed 1234
51
+ config.order = :random
52
+
53
+ # Seed global randomization in this process using the `--seed` CLI option.
54
+ # Setting this allows you to use `--seed` to deterministically reproduce
55
+ # test failures related to randomization by passing the same `--seed` value
56
+ # as the one that triggered the failure.
57
+ Kernel.srand config.seed
58
+
59
+ # rspec-expectations config goes here. You can use an alternate
60
+ # assertion/expectation library such as wrong or the stdlib/minitest
61
+ # assertions if you prefer.
62
+ config.expect_with :rspec do |expectations|
63
+ # Enable only the newer, non-monkey-patching expect syntax.
64
+ # For more details, see:
65
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
66
+ expectations.syntax = :expect
67
+ end
68
+
69
+ # rspec-mocks config goes here. You can use an alternate test double
70
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
71
+ config.mock_with :rspec do |mocks|
72
+ # Enable only the newer, non-monkey-patching expect syntax.
73
+ # For more details, see:
74
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
75
+ mocks.syntax = :expect
76
+
77
+ # Prevents you from mocking or stubbing a method that does not exist on
78
+ # a real object. This is generally recommended.
79
+ mocks.verify_partial_doubles = true
80
+ end
81
+ =end
82
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: better-uuid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Barry Allard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDOjCCAiKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBDMRUwEwYDVQQDDAxiYXJy
14
+ eS5hbGxhcmQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkW
15
+ A2NvbTAeFw0xMzA0MDgwMTI0NThaFw0xNDA0MDgwMTI0NThaMEMxFTATBgNVBAMM
16
+ DGJhcnJ5LmFsbGFyZDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPy
17
+ LGQBGRYDY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDcmlxJH
18
+ eySiUBcYTqGXaWETRVYmgfGwWRPZzqkmBdIVZkbk9SWxseiHWIReFWjP438UoUTs
19
+ J17G/HuQb0SmjPCMZy8967Fb2wqs+QRbcmpnmtYA1vilgC2CIzntFOFLSA2KpfZH
20
+ dJSsg6aaXqwS4/KJxK6ooDsp+iR6zGTINwkdUt4ktpqgCHz1VYuzvii2slnazbm4
21
+ cQUi/wWIynHyzzdrPvDhGgaZm161MYHidCtV+wzqwjeVeFsyQwCFVEkrD/0G98ho
22
+ Gti8vB6Xj6VjO3n+kh/KlYZgmM7SWauLpo+2RGlIYVYdpQQWGwhMEmvSgBxjfX4c
23
+ unDFxO1ZAQIRBQIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBS+Kk7ypi9u
24
+ kFUcaqJlpaKO7eWiUTALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBALie
25
+ YCNeW9EIQ/j8+2emMm0484JVtycOqPyIu5UALtsU42En392HVOZ6oEA/rh2KFRvq
26
+ dcDwcJPI/u7PzWp9TNp81PTShtHMtSs7Wv1UsC04vQ9b6XBEomWbbzoxxgzyjP7l
27
+ ZV4L5HzmX0nDOSEFJyYkqbwgYjIoldg2TMlw2BeoVqGm7Gx1ljXKb2Kg5iasyDpI
28
+ C/gAiGBIAX7FxyIXmjZq38xWBOxyGF3NFL/W6z+vhJg81HGdNBCpIdwrQ/eXOjba
29
+ VqwwfY+Ms3gcCHSERG1X4AFW1zesX+UWcTCwVLtAsuRWQhC8odDSVDWzUfkZmOQt
30
+ ViIxU1ZphInql7L5g34=
31
+ -----END CERTIFICATE-----
32
+ date: 2014-04-02 00:00:00.000000000 Z
33
+ dependencies:
34
+ - !ruby/object:Gem::Dependency
35
+ name: rake
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: should_not
64
+ requirement: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ type: :development
70
+ prerelease: false
71
+ version_requirements: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ - !ruby/object:Gem::Dependency
77
+ name: absolute_time
78
+ requirement: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ description: Sensible UUID library as a gem
91
+ email:
92
+ - barry.allard@gmail.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - ".rspec"
98
+ - LICENSE
99
+ - README.md
100
+ - Rakefile
101
+ - lib/benchmark.rb
102
+ - lib/better-uuid.rb
103
+ - lib/better-uuid/class.rb
104
+ - lib/better-uuid/class_methods.rb
105
+ - lib/better-uuid/instance_methods.rb
106
+ - lib/better-uuid/namespace.rb
107
+ - lib/better-uuid/nil.rb
108
+ - lib/better-uuid/state_file.rb
109
+ - lib/better-uuid/struct.rb
110
+ - lib/better-uuid/version.rb
111
+ - lib/better-uuid/versions.rb
112
+ - spec/better-uuid_spec.rb
113
+ - spec/spec_helper.rb
114
+ homepage: https://github.com/steakknife/better-uuid
115
+ licenses: []
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.2.2
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: UUID library
137
+ test_files:
138
+ - spec/better-uuid_spec.rb
139
+ - spec/spec_helper.rb
140
+ - ".rspec"
141
+ has_rdoc:
metadata.gz.sig ADDED
Binary file