gabe-uuid 0.3
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.
- data/LICENSE +20 -0
- data/README.markdown +13 -0
- data/Rakefile +30 -0
- data/lib/compat/securerandom.rb +182 -0
- data/lib/uuid.rb +128 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/uuid_spec.rb +87 -0
- metadata +59 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Gabriel Boyer
|
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.markdown
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
UUID
|
2
|
+
====
|
3
|
+
|
4
|
+
A simple library for generating/using Universally Unique Identifiers, as defined
|
5
|
+
in RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt).
|
6
|
+
|
7
|
+
This library generates version 4 UUIDs, which are based on random bytes read from
|
8
|
+
SecureRandom (included for Ruby <1.8.7).
|
9
|
+
|
10
|
+
Author
|
11
|
+
------
|
12
|
+
|
13
|
+
Gabriel Boyer (gboyer@gmail.com)
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "rake/gempackagetask"
|
2
|
+
require "spec/rake/spectask"
|
3
|
+
|
4
|
+
task :default => :spec
|
5
|
+
|
6
|
+
desc "Run all specs"
|
7
|
+
Spec::Rake::SpecTask.new("spec") do |task|
|
8
|
+
task.spec_opts = ["--format", "specdoc", "--colour"]
|
9
|
+
task.spec_files = ["spec/**/*_spec.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
spec = Gem::Specification.new do |s|
|
13
|
+
s.name = 'uuid'
|
14
|
+
s.version = '0.3'
|
15
|
+
s.platform = Gem::Platform::RUBY
|
16
|
+
s.author = 'Gabriel Boyer'
|
17
|
+
s.email = 'gboyer@gmail.com'
|
18
|
+
s.homepage = 'http://github.com/gabe/uuid/'
|
19
|
+
s.summary = 'Simple UUID implementation'
|
20
|
+
s.description = 'Simple UUID implementation, as per RFC 4122'
|
21
|
+
s.require_path = "lib"
|
22
|
+
s.files = %w[ LICENSE README.markdown Rakefile
|
23
|
+
spec/spec_helper.rb spec/uuid_spec.rb
|
24
|
+
lib/uuid.rb lib/compat/securerandom.rb ]
|
25
|
+
s.required_ruby_version = ">= 1.8.6"
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::GemPackageTask.new(spec) do |package|
|
29
|
+
package.gem_spec = spec
|
30
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# = Secure random number generator interface.
|
2
|
+
#
|
3
|
+
# This library is an interface for secure random number generator which is
|
4
|
+
# suitable for generating session key in HTTP cookies, etc.
|
5
|
+
#
|
6
|
+
# It supports following secure random number generators.
|
7
|
+
#
|
8
|
+
# * openssl
|
9
|
+
# * /dev/urandom
|
10
|
+
# * Win32
|
11
|
+
#
|
12
|
+
# == Example
|
13
|
+
#
|
14
|
+
# # random hexadecimal string.
|
15
|
+
# p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
|
16
|
+
# p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
|
17
|
+
# p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
|
18
|
+
# p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
|
19
|
+
# p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
|
20
|
+
# ...
|
21
|
+
#
|
22
|
+
# # random base64 string.
|
23
|
+
# p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
|
24
|
+
# p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
|
25
|
+
# p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
|
26
|
+
# p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
|
27
|
+
# p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
|
28
|
+
# p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="
|
29
|
+
# ...
|
30
|
+
#
|
31
|
+
# # random binary string.
|
32
|
+
# p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
|
33
|
+
# p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
|
34
|
+
# ...
|
35
|
+
|
36
|
+
begin
|
37
|
+
require 'openssl'
|
38
|
+
rescue LoadError
|
39
|
+
end
|
40
|
+
|
41
|
+
module SecureRandom
|
42
|
+
# SecureRandom.random_bytes generates a random binary string.
|
43
|
+
#
|
44
|
+
# The argument n specifies the length of the result string.
|
45
|
+
#
|
46
|
+
# If n is not specified, 16 is assumed.
|
47
|
+
# It may be larger in future.
|
48
|
+
#
|
49
|
+
# If secure random number generator is not available,
|
50
|
+
# NotImplementedError is raised.
|
51
|
+
def self.random_bytes(n=nil)
|
52
|
+
n ||= 16
|
53
|
+
|
54
|
+
if defined? OpenSSL::Random
|
55
|
+
return OpenSSL::Random.random_bytes(n)
|
56
|
+
end
|
57
|
+
|
58
|
+
if !defined?(@has_urandom) || @has_urandom
|
59
|
+
flags = File::RDONLY
|
60
|
+
flags |= File::NONBLOCK if defined? File::NONBLOCK
|
61
|
+
flags |= File::NOCTTY if defined? File::NOCTTY
|
62
|
+
flags |= File::NOFOLLOW if defined? File::NOFOLLOW
|
63
|
+
begin
|
64
|
+
File.open("/dev/urandom", flags) {|f|
|
65
|
+
unless f.stat.chardev?
|
66
|
+
raise Errno::ENOENT
|
67
|
+
end
|
68
|
+
@has_urandom = true
|
69
|
+
ret = f.readpartial(n)
|
70
|
+
if ret.length != n
|
71
|
+
raise NotImplementedError, "Unexpected partial read from random device"
|
72
|
+
end
|
73
|
+
return ret
|
74
|
+
}
|
75
|
+
rescue Errno::ENOENT
|
76
|
+
@has_urandom = false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
if !defined?(@has_win32)
|
81
|
+
begin
|
82
|
+
require 'Win32API'
|
83
|
+
|
84
|
+
crypt_acquire_context = Win32API.new("advapi32", "CryptAcquireContext", 'PPPII', 'L')
|
85
|
+
@crypt_gen_random = Win32API.new("advapi32", "CryptGenRandom", 'LIP', 'L')
|
86
|
+
|
87
|
+
hProvStr = " " * 4
|
88
|
+
prov_rsa_full = 1
|
89
|
+
crypt_verifycontext = 0xF0000000
|
90
|
+
|
91
|
+
if crypt_acquire_context.call(hProvStr, nil, nil, prov_rsa_full, crypt_verifycontext) == 0
|
92
|
+
raise SystemCallError, "CryptAcquireContext failed: #{lastWin32ErrorMessage}"
|
93
|
+
end
|
94
|
+
@hProv, = hProvStr.unpack('L')
|
95
|
+
|
96
|
+
@has_win32 = true
|
97
|
+
rescue LoadError
|
98
|
+
@has_win32 = false
|
99
|
+
end
|
100
|
+
end
|
101
|
+
if @has_win32
|
102
|
+
bytes = " " * n
|
103
|
+
if @crypt_gen_random.call(@hProv, bytes.size, bytes) == 0
|
104
|
+
raise SystemCallError, "CryptGenRandom failed: #{lastWin32ErrorMessage}"
|
105
|
+
end
|
106
|
+
return bytes
|
107
|
+
end
|
108
|
+
|
109
|
+
raise NotImplementedError, "No random device"
|
110
|
+
end
|
111
|
+
|
112
|
+
# SecureRandom.hex generates a random hex string.
|
113
|
+
#
|
114
|
+
# The argument n specifies the length of the random length.
|
115
|
+
# The length of the result string is twice of n.
|
116
|
+
#
|
117
|
+
# If n is not specified, 16 is assumed.
|
118
|
+
# It may be larger in future.
|
119
|
+
#
|
120
|
+
# If secure random number generator is not available,
|
121
|
+
# NotImplementedError is raised.
|
122
|
+
def self.hex(n=nil)
|
123
|
+
random_bytes(n).unpack("H*")[0]
|
124
|
+
end
|
125
|
+
|
126
|
+
# SecureRandom.base64 generates a random base64 string.
|
127
|
+
#
|
128
|
+
# The argument n specifies the length of the random length.
|
129
|
+
# The length of the result string is about 4/3 of n.
|
130
|
+
#
|
131
|
+
# If n is not specified, 16 is assumed.
|
132
|
+
# It may be larger in future.
|
133
|
+
#
|
134
|
+
# If secure random number generator is not available,
|
135
|
+
# NotImplementedError is raised.
|
136
|
+
def self.base64(n=nil)
|
137
|
+
[random_bytes(n)].pack("m*").delete("\n")
|
138
|
+
end
|
139
|
+
|
140
|
+
# SecureRandom.random_number generates a random number.
|
141
|
+
#
|
142
|
+
# If an positive integer is given as n,
|
143
|
+
# SecureRandom.random_number returns an integer:
|
144
|
+
# 0 <= SecureRandom.random_number(n) < n.
|
145
|
+
#
|
146
|
+
# If 0 is given or an argument is not given,
|
147
|
+
# SecureRandom.random_number returns an float:
|
148
|
+
# 0.0 <= SecureRandom.random_number() < 1.0.
|
149
|
+
def self.random_number(n=0)
|
150
|
+
if 0 < n
|
151
|
+
hex = n.to_s(16)
|
152
|
+
hex = '0' + hex if (hex.length & 1) == 1
|
153
|
+
bin = [hex].pack("H*")
|
154
|
+
mask = bin[0].ord
|
155
|
+
mask |= mask >> 1
|
156
|
+
mask |= mask >> 2
|
157
|
+
mask |= mask >> 4
|
158
|
+
begin
|
159
|
+
rnd = SecureRandom.random_bytes(bin.length)
|
160
|
+
rnd[0] = (rnd[0].ord & mask).chr
|
161
|
+
end until rnd < bin
|
162
|
+
rnd.unpack("H*")[0].hex
|
163
|
+
else
|
164
|
+
# assumption: Float::MANT_DIG <= 64
|
165
|
+
i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
|
166
|
+
Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Following code is based on David Garamond's GUID library for Ruby.
|
171
|
+
def self.lastWin32ErrorMessage # :nodoc:
|
172
|
+
get_last_error = Win32API.new("kernel32", "GetLastError", '', 'L')
|
173
|
+
format_message = Win32API.new("kernel32", "FormatMessageA", 'LPLLPLPPPPPPPP', 'L')
|
174
|
+
format_message_ignore_inserts = 0x00000200
|
175
|
+
format_message_from_system = 0x00001000
|
176
|
+
|
177
|
+
code = get_last_error.call
|
178
|
+
msg = "\0" * 1024
|
179
|
+
len = format_message.call(format_message_ignore_inserts + format_message_from_system, 0, code, 0, msg, 1024, nil, nil, nil, nil, nil, nil, nil, nil)
|
180
|
+
msg[0, len].tr("\r", '').chomp
|
181
|
+
end
|
182
|
+
end
|
data/lib/uuid.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
begin
|
2
|
+
require 'securerandom'
|
3
|
+
rescue LoadError
|
4
|
+
require File.join(File.dirname(__FILE__), 'compat', 'securerandom')
|
5
|
+
end
|
6
|
+
|
7
|
+
class UUID
|
8
|
+
def initialize(value = nil)
|
9
|
+
@value = Integer(value)
|
10
|
+
unless (@value >= 0) && (@value < (1 << 128))
|
11
|
+
raise RangeError, "#{value} (Integer value #{@value}) is out of range (need unsigned 128-bit value)"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
eql?(other)
|
17
|
+
end
|
18
|
+
|
19
|
+
def clock_seq
|
20
|
+
((clock_seq_hi_variant & 0x3f) << 8) | clock_seq_low
|
21
|
+
end
|
22
|
+
|
23
|
+
def clock_seq_hi_variant
|
24
|
+
(to_i >> 56) & 0xff
|
25
|
+
end
|
26
|
+
|
27
|
+
def clock_seq_low
|
28
|
+
(to_i >> 48) & 0xff
|
29
|
+
end
|
30
|
+
|
31
|
+
def eql?(other)
|
32
|
+
other.is_a?(self.class) && (other.to_i == to_i)
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash
|
36
|
+
to_i.hash
|
37
|
+
end
|
38
|
+
|
39
|
+
def hex
|
40
|
+
'%032x' % to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def inspect
|
44
|
+
to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
def node
|
48
|
+
to_i & 0xffffffffffff
|
49
|
+
end
|
50
|
+
|
51
|
+
def time
|
52
|
+
((time_hi_version & 0x0fff) << 48) | (time_mid << 32) | time_low
|
53
|
+
end
|
54
|
+
|
55
|
+
def time_hi_version
|
56
|
+
(to_i >> 64) & 0xffff
|
57
|
+
end
|
58
|
+
|
59
|
+
def time_low
|
60
|
+
(to_i >> 96)
|
61
|
+
end
|
62
|
+
|
63
|
+
def time_mid
|
64
|
+
(to_i >> 80) & 0xffff
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_i
|
68
|
+
@value
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
h = hex
|
73
|
+
'%s-%s-%s-%s-%s' % [h[0...8], h[8...12], h[12...16], h[16...20], h[20...32]]
|
74
|
+
end
|
75
|
+
|
76
|
+
def urn
|
77
|
+
"urn:uuid:#{self}"
|
78
|
+
end
|
79
|
+
|
80
|
+
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
|
81
|
+
'reserved for NCS compatibility',
|
82
|
+
'specified in RFC 4122',
|
83
|
+
'reserved for Microsoft compatibility',
|
84
|
+
'reserved for future definition'
|
85
|
+
]
|
86
|
+
|
87
|
+
def variant
|
88
|
+
case 0
|
89
|
+
when to_i & (0x8000 << 48)
|
90
|
+
RESERVED_NCS
|
91
|
+
when to_i & (0x4000 << 48)
|
92
|
+
RFC_4122
|
93
|
+
when to_i & (0x2000 << 48)
|
94
|
+
RESERVED_MICROSOFT
|
95
|
+
else
|
96
|
+
RESERVED_FUTURE
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def version
|
101
|
+
(variant == RFC_4122) ? ((to_i >> 76) & 0xf) : nil
|
102
|
+
end
|
103
|
+
|
104
|
+
class << self
|
105
|
+
def parse(uuid)
|
106
|
+
str = uuid.to_s
|
107
|
+
unless str =~ /^(urn:uuid:)?[0-9a-fA-F]{8}((-)?[0-9a-fA-F]{4}){3}(-)?[0-9a-fA-F]{12}$/
|
108
|
+
raise ArgumentError, "#{str} is not a recognized UUID representation"
|
109
|
+
end
|
110
|
+
new bytes_to_i(str.gsub(/(^urn:uuid:|-)/, '').downcase.unpack('a2' * 16).collect { |x| x.to_i(16) }.pack('C*'))
|
111
|
+
end
|
112
|
+
|
113
|
+
def uuid4
|
114
|
+
bytes = SecureRandom.random_bytes(16)
|
115
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40
|
116
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80
|
117
|
+
new bytes_to_i(bytes)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def bytes_to_i(bytes)
|
123
|
+
bytes.unpack('C*').inject { |value, i| value * 256 | i }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
UUID::Nil = UUID.new(0)
|
data/spec/spec_helper.rb
ADDED
data/spec/uuid_spec.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe UUID, '.uuid4' do
|
4
|
+
it 'generates a new UUID' do
|
5
|
+
UUID.uuid4.should be_a_kind_of(UUID)
|
6
|
+
UUID.uuid4.should_not == UUID.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'generates version 4 UUIDs' do
|
10
|
+
UUID.uuid4.to_s.should =~ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
|
11
|
+
UUID.uuid4.version.should == 4
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'generates UUIDs of the RFC 4122 variant' do
|
15
|
+
UUID.uuid4.variant.should == UUID::RFC_4122
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe UUID, '.parse' do
|
20
|
+
it 'creates a UUID from a valid string representation when passed one' do
|
21
|
+
id = UUID.uuid4
|
22
|
+
[id.to_s, id.hex, id.urn].each do |s|
|
23
|
+
UUID.parse(s).should == id
|
24
|
+
end
|
25
|
+
UUID.parse(UUID::Nil.to_s).should == UUID::Nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'raises an ArgumentError when passed a string it cannot parse into a UUID' do
|
29
|
+
lambda { UUID.parse '<garbage>' }.should raise_error(ArgumentError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe UUID, '#initialize' do
|
34
|
+
it 'creates a UUID from an Integer when passed one that is within range for a UUID' do
|
35
|
+
id = UUID.uuid4
|
36
|
+
UUID.new(id.to_i).should == id
|
37
|
+
UUID.new(0).should == UUID::Nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'raises an ArgumentError when passed a parameter that cannot be coerced into an Integer' do
|
41
|
+
lambda { UUID.new '<garbage>' }.should raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises a RangeError when passed an Integer that is out of range for a UUID' do
|
45
|
+
lambda { UUID.new -1 }.should raise_error(RangeError)
|
46
|
+
lambda { UUID.new(1 << 128) }.should raise_error(RangeError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe UUID, '#to_i' do
|
51
|
+
it 'returns an unsigned integer representation of the UUID' do
|
52
|
+
i = UUID.uuid4.to_i
|
53
|
+
i.should be_a_kind_of(Integer)
|
54
|
+
i.should >= 0
|
55
|
+
i.should < (1 << 128)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
delimited_hex_format = /[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}/
|
60
|
+
|
61
|
+
describe UUID, '#to_s' do
|
62
|
+
it 'returns a UUID string in delimited hex format (i.e., xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)' do
|
63
|
+
UUID.new.to_s.should =~ /^#{delimited_hex_format}$/
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe UUID, '#hex' do
|
68
|
+
it 'returns a UUID string in undelimited hex format (i.e., xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)' do
|
69
|
+
UUID.new.hex.should =~ /^[0-9a-fA-F]{8}([0-9a-fA-F]{4}){3}[0-9a-fA-F]{12}$/
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe UUID, '#urn' do
|
74
|
+
it 'returns a UUID string in delimited hex format with a urn prefix (i.e., urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)' do
|
75
|
+
UUID.new.urn.should =~ /^urn:uuid:#{delimited_hex_format}$/
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'UUID::Nil' do
|
80
|
+
it 'has a string representation (#to_s) of 00000000-0000-0000-0000-000000000000' do
|
81
|
+
UUID::Nil.to_s.should == '00000000-0000-0000-0000-000000000000'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'has an integer value (#to_i) of 0' do
|
85
|
+
UUID::Nil.to_i.should == 0
|
86
|
+
end
|
87
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gabe-uuid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.3"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabriel Boyer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-08-13 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Simple UUID implementation, as per RFC 4122
|
17
|
+
email: gboyer@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- LICENSE
|
26
|
+
- README.markdown
|
27
|
+
- Rakefile
|
28
|
+
- spec/spec_helper.rb
|
29
|
+
- spec/uuid_spec.rb
|
30
|
+
- lib/uuid.rb
|
31
|
+
- lib/compat/securerandom.rb
|
32
|
+
has_rdoc: false
|
33
|
+
homepage: http://github.com/gabe/uuid/
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.8.6
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.2.0
|
55
|
+
signing_key:
|
56
|
+
specification_version: 2
|
57
|
+
summary: Simple UUID implementation
|
58
|
+
test_files: []
|
59
|
+
|