uuidtools 2.1.5 → 3.0.0
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 +5 -5
- data/CHANGELOG +10 -0
- data/README.md +2 -4
- data/lib/uuidtools/version.rb +3 -3
- data/lib/uuidtools.rb +142 -55
- data/spec/uuidtools/mac_address_spec.rb +17 -3
- data/spec/uuidtools/uuid_creation_spec.rb +31 -30
- data/spec/uuidtools/uuid_parsing_spec.rb +38 -1
- data/tasks/benchmark.rake +46 -27
- data/tasks/gem.rake +3 -8
- data/uuidtools.gemspec +28 -0
- metadata +9 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3a3a7b4cd84917d78bc44482023ea1e337b407b176dda81fc097f1617bfb1545
|
4
|
+
data.tar.gz: 9af85de9393ea8752ee5cba3feff96f2ba7994dd4092bea6dcae5bdb6229c12f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31987aae1c0376ca5cece706c0532e900c4033cc8923c86aa97aa2cb974fd817dcc5749935be8a525050c6b070ab98d268ebe4b826f508bff041adfe125ee75
|
7
|
+
data.tar.gz: 37ee507b3aa1bef02ebabc4ddfbc496ee3339ef5664134f52ebeb31044e8065935aa39088bfe2b7594745a4ff8d3c0f14b53a098a59d98f9ff54a62148903b69
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== UUIDTools 3.0.0
|
2
|
+
* more strict validation, accept variants with most significant bits set to 1 and 0
|
3
|
+
* v6, v7, v8 UUIDs are now considered valid
|
4
|
+
* better MAC address behavior for container environments
|
5
|
+
* windows MAC address detection now uses a fallback location like other OSes
|
6
|
+
* frozen string literal fixes
|
7
|
+
== UUIDTools 2.2.0
|
8
|
+
* drop support for ruby < 2.3
|
9
|
+
* use Integer vs Fixnum
|
10
|
+
* performance improvements
|
1
11
|
== UUIDTools 2.1.5
|
2
12
|
* fixed issue with ip command vs ifconfig
|
3
13
|
* dumped RubyForge related cruft
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](http://travis-ci.org/sporkmonger/uuidtools)
|
2
|
+
|
1
3
|
# UUIDTools
|
2
4
|
|
3
5
|
<dl>
|
@@ -7,10 +9,6 @@
|
|
7
9
|
<dt>License</dt><dd>Apache 2.0</dd>
|
8
10
|
</dl>
|
9
11
|
|
10
|
-
[](http://travis-ci.org/sporkmonger/uuidtools)
|
11
|
-
[](https://gemnasium.com/sporkmonger/uuidtools)
|
12
|
-
[](https://www.gittip.com/sporkmonger/ "Support Open Source Development w/ Gittip")
|
13
|
-
|
14
12
|
# Description
|
15
13
|
|
16
14
|
UUIDTools was designed to be a simple library for generating any
|
data/lib/uuidtools/version.rb
CHANGED
data/lib/uuidtools.rb
CHANGED
@@ -164,7 +164,7 @@ module UUIDTools
|
|
164
164
|
clock_seq_hi_and_reserved = uuid_components[3].to_i(16)
|
165
165
|
clock_seq_low = uuid_components[4].to_i(16)
|
166
166
|
nodes = []
|
167
|
-
|
167
|
+
6.times do |i|
|
168
168
|
nodes << uuid_components[5][(i * 2)..(i * 2) + 1].to_i(16)
|
169
169
|
end
|
170
170
|
return self.new(time_low, time_mid, time_hi_and_version,
|
@@ -178,19 +178,52 @@ module UUIDTools
|
|
178
178
|
raise TypeError,
|
179
179
|
"Expected String, got #{raw_string.class.name} instead."
|
180
180
|
end
|
181
|
-
integer = self.convert_byte_string_to_int(raw_string)
|
182
181
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
182
|
+
if raw_string.respond_to?(:force_encoding)
|
183
|
+
raw_string.force_encoding(Encoding::ASCII_8BIT)
|
184
|
+
end
|
185
|
+
|
186
|
+
raw_length = raw_string.length
|
187
|
+
if raw_length < 16
|
188
|
+
# Option A: Enforce raw_string be 16 characters (More strict)
|
189
|
+
#raise ArgumentError,
|
190
|
+
# "Expected 16 bytes, got #{raw_string.length} instead."
|
191
|
+
|
192
|
+
# Option B: Pad raw_string to 16 characters (Compatible with existing behavior)
|
193
|
+
raw_string = raw_string.rjust(16, "\0")
|
194
|
+
elsif raw_length > 16
|
195
|
+
# NOTE: As per "Option B" above, existing behavior would use the lower
|
196
|
+
# 128-bits of an overly long raw_string instead of using the upper 128-bits.
|
197
|
+
start_index = raw_length - 16
|
198
|
+
raw_string = raw_string[start_index...raw_length]
|
199
|
+
end
|
200
|
+
|
201
|
+
raw_bytes = []
|
202
|
+
if raw_string[0].respond_to? :ord
|
203
|
+
for i in 0...raw_string.size
|
204
|
+
raw_bytes << raw_string[i].ord
|
205
|
+
end
|
206
|
+
else
|
207
|
+
raw_bytes = raw_string
|
208
|
+
end
|
209
|
+
|
210
|
+
time_low = ((raw_bytes[0] << 24) +
|
211
|
+
(raw_bytes[1] << 16) +
|
212
|
+
(raw_bytes[2] << 8) +
|
213
|
+
raw_bytes[3])
|
214
|
+
time_mid = ((raw_bytes[4] << 8) +
|
215
|
+
raw_bytes[5])
|
216
|
+
time_hi_and_version = ((raw_bytes[6] << 8) +
|
217
|
+
raw_bytes[7])
|
218
|
+
clock_seq_hi_and_reserved = raw_bytes[8]
|
219
|
+
clock_seq_low = raw_bytes[9]
|
188
220
|
nodes = []
|
189
|
-
for i in
|
190
|
-
nodes <<
|
221
|
+
for i in 10...16
|
222
|
+
nodes << raw_bytes[i]
|
191
223
|
end
|
224
|
+
|
192
225
|
return self.new(time_low, time_mid, time_hi_and_version,
|
193
|
-
|
226
|
+
clock_seq_hi_and_reserved, clock_seq_low, nodes)
|
194
227
|
end
|
195
228
|
|
196
229
|
##
|
@@ -200,17 +233,42 @@ module UUIDTools
|
|
200
233
|
raise ArgumentError,
|
201
234
|
"Expected Integer, got #{uuid_int.class.name} instead."
|
202
235
|
end
|
203
|
-
|
236
|
+
|
237
|
+
time_low = (uuid_int >> 96) & 0xFFFFFFFF
|
238
|
+
time_mid = (uuid_int >> 80) & 0xFFFF
|
239
|
+
time_hi_and_version = (uuid_int >> 64) & 0xFFFF
|
240
|
+
clock_seq_hi_and_reserved = (uuid_int >> 56) & 0xFF
|
241
|
+
clock_seq_low = (uuid_int >> 48) & 0xFF
|
242
|
+
nodes = []
|
243
|
+
for i in 0..5
|
244
|
+
nodes << ((uuid_int >> (40 - (i * 8))) & 0xFF)
|
245
|
+
end
|
246
|
+
|
247
|
+
return self.new(time_low, time_mid, time_hi_and_version,
|
248
|
+
clock_seq_hi_and_reserved, clock_seq_low, nodes)
|
204
249
|
end
|
205
250
|
|
206
251
|
##
|
207
252
|
# Parse a UUID from a hexdigest String.
|
208
|
-
def self.parse_hexdigest(
|
209
|
-
unless
|
253
|
+
def self.parse_hexdigest(uuid_hex)
|
254
|
+
unless uuid_hex.kind_of?(String)
|
210
255
|
raise ArgumentError,
|
211
|
-
"Expected String, got #{
|
256
|
+
"Expected String, got #{uuid_hex.class.name} instead."
|
257
|
+
end
|
258
|
+
|
259
|
+
time_low = uuid_hex[0...8].to_i(16)
|
260
|
+
time_mid = uuid_hex[8...12].to_i(16)
|
261
|
+
time_hi_and_version = uuid_hex[12...16].to_i(16)
|
262
|
+
clock_seq_hi_and_reserved = uuid_hex[16...18].to_i(16)
|
263
|
+
clock_seq_low = uuid_hex[18...20].to_i(16)
|
264
|
+
nodes_string = uuid_hex[20...32]
|
265
|
+
nodes = []
|
266
|
+
for i in 0..5
|
267
|
+
nodes << nodes_string[(i * 2)..(i * 2) + 1].to_i(16)
|
212
268
|
end
|
213
|
-
|
269
|
+
|
270
|
+
return self.new(time_low, time_mid, time_hi_and_version,
|
271
|
+
clock_seq_hi_and_reserved, clock_seq_low, nodes)
|
214
272
|
end
|
215
273
|
|
216
274
|
##
|
@@ -249,7 +307,7 @@ module UUIDTools
|
|
249
307
|
nodes = SecureRandom.random_bytes(6).unpack("C*")
|
250
308
|
nodes[0] |= 0b00000001
|
251
309
|
end
|
252
|
-
|
310
|
+
6.times do |i|
|
253
311
|
node_id += (nodes[i] << (40 - (i * 8)))
|
254
312
|
end
|
255
313
|
clock_sequence = @@last_clock_sequence
|
@@ -358,12 +416,7 @@ module UUIDTools
|
|
358
416
|
##
|
359
417
|
# Returns true if this UUID is valid.
|
360
418
|
def valid?
|
361
|
-
|
362
|
-
(1..5).include?(self.version)
|
363
|
-
return true
|
364
|
-
else
|
365
|
-
return false
|
366
|
-
end
|
419
|
+
return self.variant == 0b100 && (1..8).cover?(self.version)
|
367
420
|
end
|
368
421
|
|
369
422
|
##
|
@@ -405,7 +458,7 @@ module UUIDTools
|
|
405
458
|
return check if check != 0
|
406
459
|
check = self.clock_seq_low <=> other_uuid.clock_seq_low
|
407
460
|
return check if check != 0
|
408
|
-
|
461
|
+
6.times do |i|
|
409
462
|
if (self.nodes[i] < other_uuid.nodes[i])
|
410
463
|
return -1
|
411
464
|
end
|
@@ -486,7 +539,7 @@ module UUIDTools
|
|
486
539
|
bytes = (time_low << 96) + (time_mid << 80) +
|
487
540
|
(time_hi_and_version << 64) + (clock_seq_hi_and_reserved << 56) +
|
488
541
|
(clock_seq_low << 48)
|
489
|
-
|
542
|
+
6.times do |i|
|
490
543
|
bytes += (nodes[i] << (40 - (i * 8)))
|
491
544
|
end
|
492
545
|
bytes
|
@@ -500,7 +553,7 @@ module UUIDTools
|
|
500
553
|
def generate_s
|
501
554
|
result = sprintf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", @time_low, @time_mid,
|
502
555
|
@time_hi_and_version, @clock_seq_hi_and_reserved, @clock_seq_low);
|
503
|
-
|
556
|
+
6.times do |i|
|
504
557
|
result << sprintf("%2.2x", @nodes[i])
|
505
558
|
end
|
506
559
|
return result.downcase
|
@@ -527,36 +580,47 @@ module UUIDTools
|
|
527
580
|
def self.os_class
|
528
581
|
require 'rbconfig'
|
529
582
|
os_platform = RbConfig::CONFIG['target_os']
|
530
|
-
os_class = nil
|
531
583
|
if (os_platform =~ /win/i && !(os_platform =~ /darwin/i)) ||
|
532
584
|
os_platform =~ /w32/i
|
533
|
-
|
585
|
+
:windows
|
534
586
|
elsif os_platform =~ /solaris/i
|
535
|
-
|
587
|
+
:solaris
|
536
588
|
elsif os_platform =~ /netbsd/i
|
537
|
-
|
589
|
+
:netbsd
|
538
590
|
elsif os_platform =~ /openbsd/i
|
539
|
-
|
591
|
+
:openbsd
|
540
592
|
end
|
541
593
|
end
|
542
594
|
|
543
595
|
# making these class variables helps with testing
|
596
|
+
@ipconfig_command = "ipconfig"
|
597
|
+
@ipconfig_path_default = "c:\\windows\\system32\\ipconfig.exe"
|
544
598
|
@ifconfig_command = "ifconfig"
|
545
599
|
@ifconfig_path_default = "/sbin/ifconfig"
|
546
600
|
@ip_command = "ip"
|
547
601
|
@ip_path_default = "/sbin/ip"
|
548
602
|
|
549
603
|
class << self
|
604
|
+
attr_accessor :ipconfig_command, :ipconfig_path_default
|
550
605
|
attr_accessor :ifconfig_command, :ifconfig_path_default
|
551
606
|
attr_accessor :ip_command, :ip_path_default
|
552
607
|
end
|
553
608
|
|
609
|
+
#
|
610
|
+
# Find the path of the ipconfig command if it is present
|
611
|
+
#
|
612
|
+
def self.ipconfig_path
|
613
|
+
path = `where #{UUID.ipconfig_command}`.strip
|
614
|
+
path = UUID.ipconfig_path_default if path == "" && File.exist?(UUID.ipconfig_path_default)
|
615
|
+
return (path === "" ? nil : path)
|
616
|
+
end
|
617
|
+
|
554
618
|
#
|
555
619
|
# Find the path of the ifconfig(8) command if it is present
|
556
620
|
#
|
557
621
|
def self.ifconfig_path
|
558
622
|
path = `which #{UUID.ifconfig_command} 2>/dev/null`.strip
|
559
|
-
path = UUID.ifconfig_path_default if
|
623
|
+
path = UUID.ifconfig_path_default if path == "" && File.exist?(UUID.ifconfig_path_default)
|
560
624
|
return (path === "" ? nil : path)
|
561
625
|
end
|
562
626
|
|
@@ -565,30 +629,41 @@ module UUIDTools
|
|
565
629
|
#
|
566
630
|
def self.ip_path
|
567
631
|
path = `which #{UUID.ip_command} 2>/dev/null`.strip
|
568
|
-
path = UUID.ip_path_default if
|
632
|
+
path = UUID.ip_path_default if path == "" && File.exist?(UUID.ip_path_default)
|
569
633
|
return (path === "" ? nil : path)
|
570
634
|
end
|
571
635
|
|
636
|
+
#
|
637
|
+
# Call the ipconfig command that is found
|
638
|
+
#
|
639
|
+
def self.ipconfig(all = nil)
|
640
|
+
ipconfig_path = UUID.ipconfig_path
|
641
|
+
command =
|
642
|
+
if ipconfig_path
|
643
|
+
"#{ipconfig_path}#{all ? ' /all' : ''}"
|
644
|
+
end
|
645
|
+
`#{command}` if command
|
646
|
+
end
|
647
|
+
|
572
648
|
#
|
573
649
|
# Call the ifconfig or ip command that is found
|
574
650
|
#
|
575
|
-
def self.ifconfig(all=nil)
|
576
|
-
# find the path of the ifconfig command
|
651
|
+
def self.ifconfig(all = nil)
|
577
652
|
ifconfig_path = UUID.ifconfig_path
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
all_switch = all == nil ? "" : "-a"
|
587
|
-
return `#{ifconfig_path} #{all_switch}` if not ifconfig_path == nil
|
653
|
+
ip_path = UUID.ip_path
|
654
|
+
command =
|
655
|
+
if ifconfig_path
|
656
|
+
"#{ifconfig_path}#{all ? ' -a' : ''}"
|
657
|
+
elsif ip_path
|
658
|
+
"#{ip_path} addr list"
|
659
|
+
end
|
660
|
+
`#{command}` if command
|
588
661
|
end
|
589
662
|
|
590
663
|
# Match and return the first Mac address found
|
591
664
|
def self.first_mac(instring)
|
665
|
+
return nil if instring.nil?
|
666
|
+
|
592
667
|
mac_regexps = [
|
593
668
|
Regexp.new("address:? (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"),
|
594
669
|
Regexp.new("addr:? (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"),
|
@@ -621,17 +696,23 @@ module UUIDTools
|
|
621
696
|
# Returns nil if a MAC address could not be found.
|
622
697
|
def self.mac_address
|
623
698
|
if !defined?(@@mac_address)
|
699
|
+
@@mac_address = nil
|
624
700
|
require 'rbconfig'
|
625
701
|
|
626
702
|
os_class = UUID.os_class
|
627
703
|
|
628
704
|
if os_class == :windows
|
629
705
|
begin
|
630
|
-
|
706
|
+
ipconfig_output = UUID.ipconfig(:all)
|
707
|
+
@@mac_address = UUID.first_mac ipconfig_output
|
631
708
|
rescue
|
632
709
|
end
|
633
|
-
else
|
634
|
-
|
710
|
+
else
|
711
|
+
ifconfig_output = UUID.ifconfig(:all)
|
712
|
+
if ifconfig_output
|
713
|
+
# linux, bsd, macos, solaris
|
714
|
+
@@mac_address = UUID.first_mac ifconfig_output
|
715
|
+
end
|
635
716
|
end
|
636
717
|
|
637
718
|
if @@mac_address != nil
|
@@ -695,11 +776,11 @@ module UUIDTools
|
|
695
776
|
##
|
696
777
|
# @api private
|
697
778
|
def self.convert_int_to_byte_string(integer, size)
|
698
|
-
byte_string = ""
|
779
|
+
byte_string = +""
|
699
780
|
if byte_string.respond_to?(:force_encoding)
|
700
781
|
byte_string.force_encoding(Encoding::ASCII_8BIT)
|
701
782
|
end
|
702
|
-
|
783
|
+
size.times do |i|
|
703
784
|
byte_string << ((integer >> (((size - 1) - i) * 8)) & 0xFF)
|
704
785
|
end
|
705
786
|
return byte_string
|
@@ -711,21 +792,27 @@ module UUIDTools
|
|
711
792
|
if byte_string.respond_to?(:force_encoding)
|
712
793
|
byte_string.force_encoding(Encoding::ASCII_8BIT)
|
713
794
|
end
|
795
|
+
|
714
796
|
integer = 0
|
715
797
|
size = byte_string.size
|
716
|
-
|
717
|
-
|
718
|
-
byte_string[i].ord
|
719
|
-
|
798
|
+
if byte_string[0].respond_to? :ord
|
799
|
+
for i in 0...size
|
800
|
+
integer += (byte_string[i].ord << (((size - 1) - i) * 8))
|
801
|
+
end
|
802
|
+
else
|
803
|
+
for i in 0...size
|
804
|
+
integer += (byte_string[i] << (((size - 1) - i) * 8))
|
805
|
+
end
|
720
806
|
end
|
807
|
+
|
721
808
|
return integer
|
722
809
|
end
|
723
810
|
end
|
724
811
|
|
725
812
|
##
|
726
813
|
# Constant Regexp that matches a UUID and captures its components.
|
727
|
-
UUID_REGEXP = Regexp.new("
|
728
|
-
"([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})
|
814
|
+
UUID_REGEXP = Regexp.new("\\A([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-" +
|
815
|
+
"([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})\\z")
|
729
816
|
|
730
817
|
##
|
731
818
|
# Constant that represents the DNS namespace.
|
@@ -213,7 +213,8 @@ samples = {
|
|
213
213
|
:openbsd => openbsd_sample,
|
214
214
|
:linux => linux_sample,
|
215
215
|
:linux2 => linux_sample_2,
|
216
|
-
:linuxip => linux_ip_sample
|
216
|
+
:linuxip => linux_ip_sample,
|
217
|
+
:docker => nil
|
217
218
|
}
|
218
219
|
|
219
220
|
macs = {
|
@@ -260,49 +261,57 @@ describe UUIDTools::UUID, "before obtaining a MAC address" do
|
|
260
261
|
end
|
261
262
|
|
262
263
|
it "should parse windows MAC addresses" do
|
263
|
-
# mock
|
264
|
-
allow(UUIDTools::UUID).to receive(:
|
264
|
+
# mock os_class() so that we don't get different mock behavior on windows
|
265
|
+
allow(UUIDTools::UUID).to receive(:os_class) { :windows }
|
266
|
+
allow(UUIDTools::UUID).to receive(:ipconfig) { samples[:windows] }
|
265
267
|
mac = UUIDTools::UUID.mac_address
|
266
268
|
expect(mac).to eql(macs[:windows])
|
267
269
|
end
|
268
270
|
|
269
271
|
it "should parse solaris MAC addresses" do
|
272
|
+
allow(UUIDTools::UUID).to receive(:os_class) { :solaris }
|
270
273
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:solaris] }
|
271
274
|
mac = UUIDTools::UUID.mac_address
|
272
275
|
expect(mac).to eql(macs[:solaris])
|
273
276
|
end
|
274
277
|
|
275
278
|
it "should parse freebsd MAC addresses" do
|
279
|
+
allow(UUIDTools::UUID).to receive(:os_class) { nil }
|
276
280
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:freebsd] }
|
277
281
|
mac = UUIDTools::UUID.mac_address
|
278
282
|
expect(mac).to eql(macs[:freebsd])
|
279
283
|
end
|
280
284
|
|
281
285
|
it "should parse openbsd MAC addresses" do
|
286
|
+
allow(UUIDTools::UUID).to receive(:os_class) { :openbsd }
|
282
287
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:openbsd] }
|
283
288
|
mac = UUIDTools::UUID.mac_address
|
284
289
|
expect(mac).to eql(macs[:openbsd])
|
285
290
|
end
|
286
291
|
|
287
292
|
it "should parse linux MAC addresses with ifconfig" do
|
293
|
+
allow(UUIDTools::UUID).to receive(:os_class) { nil }
|
288
294
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:linux] }
|
289
295
|
mac = UUIDTools::UUID.mac_address
|
290
296
|
expect(mac).to eql(macs[:linux])
|
291
297
|
end
|
292
298
|
|
293
299
|
it "should parse a linux HWaddr address with ifconfig" do
|
300
|
+
allow(UUIDTools::UUID).to receive(:os_class) { nil }
|
294
301
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:linux2] }
|
295
302
|
mac = UUIDTools::UUID.mac_address
|
296
303
|
expect(mac).to eql(macs[:linux2])
|
297
304
|
end
|
298
305
|
|
299
306
|
it "should parse macos MAC addresses with ifconfig" do
|
307
|
+
allow(UUIDTools::UUID).to receive(:os_class) { nil }
|
300
308
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:macos] }
|
301
309
|
mac = UUIDTools::UUID.mac_address
|
302
310
|
expect(mac).to eql(macs[:macos])
|
303
311
|
end
|
304
312
|
|
305
313
|
it "should parse linux MAC addresses with ip" do
|
314
|
+
allow(UUIDTools::UUID).to receive(:os_class) { nil }
|
306
315
|
allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:linuxip] }
|
307
316
|
mac = UUIDTools::UUID.mac_address
|
308
317
|
expect(mac).to eql(macs[:linuxip])
|
@@ -451,4 +460,9 @@ describe UUIDTools::UUID, "before obtaining a MAC address" do
|
|
451
460
|
mac = UUIDTools::UUID.first_mac samples[:linuxip]
|
452
461
|
expect(mac).to eql(macs[:linuxip])
|
453
462
|
end
|
463
|
+
|
464
|
+
it "should return nil when unable to identify the mac address" do
|
465
|
+
mac = UUIDTools::UUID.first_mac nil
|
466
|
+
expect(mac).to be_nil
|
467
|
+
end
|
454
468
|
end
|
@@ -14,6 +14,7 @@ describe UUIDTools::UUID, "when generating" do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should correctly generate timestamp variant UUIDs" do
|
17
|
+
allow(UUIDTools::UUID).to receive(:mac_address) { "aa:bb:cc:dd:ee:ff" }
|
17
18
|
expect(UUIDTools::UUID.timestamp_create).not_to be_random_node_id
|
18
19
|
expect(UUIDTools::UUID.timestamp_create.to_s).not_to eql(
|
19
20
|
UUIDTools::UUID.timestamp_create.to_s
|
@@ -54,77 +55,77 @@ describe UUIDTools::UUID, "when generating" do
|
|
54
55
|
end
|
55
56
|
|
56
57
|
it "should throw an exception if a segment has an invalid value" do
|
57
|
-
expect
|
58
|
+
expect do
|
58
59
|
UUIDTools::UUID.new(-1, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])
|
59
|
-
end
|
60
|
-
expect
|
60
|
+
end.to raise_error(ArgumentError)
|
61
|
+
expect do
|
61
62
|
UUIDTools::UUID.new(4294967296, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])
|
62
|
-
end
|
63
|
+
end.to raise_error(ArgumentError)
|
63
64
|
end
|
64
65
|
|
65
66
|
it "should throw an exception if a segment has an invalid value" do
|
66
|
-
expect
|
67
|
+
expect do
|
67
68
|
UUIDTools::UUID.new(0, -1, 0, 0, 0, [0, 0, 0, 0, 0, 0])
|
68
|
-
end
|
69
|
-
expect
|
69
|
+
end.to raise_error(ArgumentError)
|
70
|
+
expect do
|
70
71
|
UUIDTools::UUID.new(0, 65536, 0, 0, 0, [0, 0, 0, 0, 0, 0])
|
71
|
-
end
|
72
|
+
end.to raise_error(ArgumentError)
|
72
73
|
end
|
73
74
|
|
74
75
|
it "should throw an exception if a segment has an invalid value" do
|
75
|
-
expect
|
76
|
+
expect do
|
76
77
|
UUIDTools::UUID.new(0, 0, -1, 0, 0, [0, 0, 0, 0, 0, 0])
|
77
|
-
end
|
78
|
-
expect
|
78
|
+
end.to raise_error(ArgumentError)
|
79
|
+
expect do
|
79
80
|
UUIDTools::UUID.new(0, 0, 65536, 0, 0, [0, 0, 0, 0, 0, 0])
|
80
|
-
end
|
81
|
+
end.to raise_error(ArgumentError)
|
81
82
|
end
|
82
83
|
|
83
84
|
it "should throw an exception if a segment has an invalid value" do
|
84
|
-
expect
|
85
|
+
expect do
|
85
86
|
UUIDTools::UUID.new(0, 0, 0, -1, 0, [0, 0, 0, 0, 0, 0])
|
86
|
-
end
|
87
|
-
expect
|
87
|
+
end.to raise_error(ArgumentError)
|
88
|
+
expect do
|
88
89
|
UUIDTools::UUID.new(0, 0, 0, 256, 0, [0, 0, 0, 0, 0, 0])
|
89
|
-
end
|
90
|
+
end.to raise_error(ArgumentError)
|
90
91
|
end
|
91
92
|
|
92
93
|
it "should throw an exception if a segment has an invalid value" do
|
93
|
-
expect
|
94
|
+
expect do
|
94
95
|
UUIDTools::UUID.new(0, 0, 0, 0, -1, [0, 0, 0, 0, 0, 0])
|
95
|
-
end
|
96
|
-
expect
|
96
|
+
end.to raise_error(ArgumentError)
|
97
|
+
expect do
|
97
98
|
UUIDTools::UUID.new(0, 0, 0, 0, 256, [0, 0, 0, 0, 0, 0])
|
98
|
-
end
|
99
|
+
end.to raise_error(ArgumentError)
|
99
100
|
end
|
100
101
|
|
101
102
|
it "should throw an exception if nodes are not a collection" do
|
102
|
-
expect
|
103
|
+
expect do
|
103
104
|
UUIDTools::UUID.new(0, 0, 0, 0, 0, :bogus)
|
104
|
-
end
|
105
|
+
end.to raise_error(TypeError)
|
105
106
|
end
|
106
107
|
|
107
108
|
it "should throw an exception if nodes are the wrong size" do
|
108
|
-
expect
|
109
|
+
expect do
|
109
110
|
UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0])
|
110
|
-
end
|
111
|
+
end.to raise_error(ArgumentError)
|
111
112
|
end
|
112
113
|
|
113
114
|
it "should throw an exception if any nodes have invalid values" do
|
114
|
-
expect
|
115
|
+
expect do
|
115
116
|
UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 256])
|
116
|
-
end
|
117
|
+
end.to raise_error(ArgumentError)
|
117
118
|
end
|
118
119
|
|
119
120
|
it "should throw an exception if parsing anything but a String" do
|
120
|
-
expect
|
121
|
+
expect do
|
121
122
|
UUIDTools::UUID.parse(:bogus)
|
122
|
-
end
|
123
|
+
end.to raise_error(TypeError)
|
123
124
|
end
|
124
125
|
|
125
126
|
it "should throw an exception if raw parsing anything but a String" do
|
126
|
-
expect
|
127
|
+
expect do
|
127
128
|
UUIDTools::UUID.parse_raw(:bogus)
|
128
|
-
end
|
129
|
+
end.to raise_error(TypeError)
|
129
130
|
end
|
130
131
|
end
|
@@ -25,6 +25,7 @@ describe UUIDTools::UUID, "when parsing" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should not treat a timestamp version UUID as a random node UUID" do
|
28
|
+
allow(UUIDTools::UUID).to receive(:mac_address) { "aa:bb:cc:dd:ee:ff" }
|
28
29
|
expect(UUIDTools::UUID.timestamp_create).not_to be_random_node_id
|
29
30
|
end
|
30
31
|
|
@@ -64,6 +65,22 @@ describe UUIDTools::UUID, "when parsing" do
|
|
64
65
|
expect(UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])).not_to be_valid
|
65
66
|
end
|
66
67
|
|
68
|
+
it "should not identify UUIDs prefixed by other strings as valid" do
|
69
|
+
expect do
|
70
|
+
UUIDTools::UUID.parse("bogus\n#{UUIDTools::UUID.random_create}")
|
71
|
+
end.to raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not identify UUIDs suffixed by other strings as valid" do
|
75
|
+
expect do
|
76
|
+
UUIDTools::UUID.parse("#{UUIDTools::UUID.random_create}\nbogus")
|
77
|
+
end.to raise_error(ArgumentError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should parse v7 UUIDs as valid" do
|
81
|
+
expect(UUIDTools::UUID.parse("01957ca6-fc1a-7322-956e-e9e6c53cab55")).to be_valid
|
82
|
+
end
|
83
|
+
|
67
84
|
it "should allow for sorting of UUID arrays" do
|
68
85
|
uuids = []
|
69
86
|
1000.times do
|
@@ -94,7 +111,7 @@ describe UUIDTools::UUID, "when parsing" do
|
|
94
111
|
it "should produce a sane hash value for a UUID" do
|
95
112
|
uuid = UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])
|
96
113
|
expect(uuid.to_i).to eql(0)
|
97
|
-
expect(uuid.hash).to be_kind_of(
|
114
|
+
expect(uuid.hash).to be_kind_of(Integer)
|
98
115
|
end
|
99
116
|
|
100
117
|
it "should produce the correct URI for a UUID" do
|
@@ -125,4 +142,24 @@ describe UUIDTools::UUID, "when parsing" do
|
|
125
142
|
uuid = UUIDTools::UUID.timestamp_create
|
126
143
|
expect(UUIDTools::UUID.parse_hexdigest(uuid.hexdigest)).to eql(uuid)
|
127
144
|
end
|
145
|
+
|
146
|
+
it "should correctly parse raw bytes" do
|
147
|
+
# NOTE: Short Input
|
148
|
+
expect(UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])).to eql(
|
149
|
+
UUIDTools::UUID.parse_raw(+"")
|
150
|
+
)
|
151
|
+
|
152
|
+
# NOTE: Nil Input
|
153
|
+
expect(
|
154
|
+
UUIDTools::UUID.parse_raw(+"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
|
155
|
+
).to be_nil_uuid
|
156
|
+
|
157
|
+
# NOTE: Realistic Input
|
158
|
+
uuid = UUIDTools::UUID.timestamp_create
|
159
|
+
expect(UUIDTools::UUID.parse_raw(uuid.raw)).to eql(uuid)
|
160
|
+
|
161
|
+
# NOTE: Long input
|
162
|
+
raw192bit = "\1\2\3\4\5\6\7\8" + uuid.raw
|
163
|
+
expect(UUIDTools::UUID.parse_raw(raw192bit)).to eql(uuid)
|
164
|
+
end
|
128
165
|
end
|
data/tasks/benchmark.rake
CHANGED
@@ -1,38 +1,57 @@
|
|
1
1
|
task :benchmark do
|
2
|
-
require 'lib/uuidtools'
|
3
2
|
require 'benchmark'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
10000.times do
|
8
|
-
UUID.timestamp_create.to_s
|
9
|
-
end
|
10
|
-
end
|
11
|
-
puts "#{(10000.0 / result.real)} version 1 per second."
|
4
|
+
$LOAD_PATH.unshift File.expand_path('../..', __FILE__)
|
5
|
+
require 'lib/uuidtools'
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
10000.times do
|
16
|
-
UUID.md5_create(UUID_URL_NAMESPACE,
|
17
|
-
"http://www.ietf.org/rfc/rfc4122.txt").to_s
|
18
|
-
end
|
7
|
+
def format_float(float)
|
8
|
+
("%.2f" % float).rjust(9, ' ')
|
19
9
|
end
|
20
|
-
puts "#{(10000.0 / result.real)} version 3 per second."
|
21
10
|
|
22
|
-
|
23
|
-
|
24
|
-
10000.times do
|
25
|
-
UUID.random_create.to_s
|
26
|
-
end
|
11
|
+
def format_result(result, action, iterations)
|
12
|
+
$stdout.puts "#{format_float(iterations / result.real)} | #{action}"
|
27
13
|
end
|
28
|
-
puts "#{(10000.0 / result.real)} version 4 per second."
|
29
14
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
UUID.sha1_create(UUID_URL_NAMESPACE,
|
34
|
-
"http://www.ietf.org/rfc/rfc4122.txt").to_s
|
15
|
+
def benchmark(name, n = 10000)
|
16
|
+
result = Benchmark.measure do
|
17
|
+
n.times { yield }
|
35
18
|
end
|
19
|
+
|
20
|
+
format_result(result, name, n)
|
36
21
|
end
|
37
|
-
|
22
|
+
|
23
|
+
$stdout.puts ' x/second | Benchmark'
|
24
|
+
$stdout.puts '---------- -----------'
|
25
|
+
|
26
|
+
##
|
27
|
+
# Benchmark UUID creation
|
28
|
+
namespace = UUIDTools::UUID_URL_NAMESPACE
|
29
|
+
url = "http://www.ietf.org/rfc/rfc4122.txt"
|
30
|
+
|
31
|
+
benchmark('Version 1') { UUIDTools::UUID.timestamp_create.to_s }
|
32
|
+
benchmark('Version 3') { UUIDTools::UUID.md5_create(namespace, url).to_s }
|
33
|
+
benchmark('Version 4') { UUIDTools::UUID.random_create.to_s }
|
34
|
+
benchmark('Version 5') { UUIDTools::UUID.sha1_create(namespace, url).to_s }
|
35
|
+
|
36
|
+
##
|
37
|
+
# Benchmark UUID parsing
|
38
|
+
uuid_s = UUIDTools::UUID.random_create.to_s
|
39
|
+
benchmark('UUID::parse', 40000) { UUIDTools::UUID.parse(uuid_s) }
|
40
|
+
|
41
|
+
uuid_raw = UUIDTools::UUID.random_create.raw
|
42
|
+
benchmark('UUID::parse_raw', 40000) { UUIDTools::UUID.parse_raw(uuid_raw) }
|
43
|
+
|
44
|
+
uuid_i = UUIDTools::UUID.random_create.to_i
|
45
|
+
benchmark('UUID::parse_int', 40000) { UUIDTools::UUID.parse_int(uuid_i) }
|
46
|
+
|
47
|
+
uuid_hex = UUIDTools::UUID.random_create.hexdigest
|
48
|
+
benchmark('UUID::parse_hexdigest', 40000) { UUIDTools::UUID.parse_hexdigest(uuid_hex) }
|
49
|
+
|
50
|
+
##
|
51
|
+
# Benchmark UUID private api
|
52
|
+
byte_string = UUIDTools::UUID.timestamp_create.raw
|
53
|
+
benchmark('UUID::convert_byte_string_to_int') { UUIDTools::UUID.convert_byte_string_to_int(byte_string) }
|
54
|
+
|
55
|
+
bigint = UUIDTools::UUID.timestamp_create.to_i
|
56
|
+
benchmark('UUID::convert_int_to_byte_string') { UUIDTools::UUID.convert_int_to_byte_string(bigint, 16) }
|
38
57
|
end
|
data/tasks/gem.rake
CHANGED
@@ -10,6 +10,7 @@ namespace :gem do
|
|
10
10
|
s.version = PKG_VERSION
|
11
11
|
s.summary = PKG_SUMMARY
|
12
12
|
s.description = PKG_DESCRIPTION
|
13
|
+
s.licenses = ["Apache-2.0"]
|
13
14
|
|
14
15
|
s.files = PKG_FILES.to_a
|
15
16
|
|
@@ -43,14 +44,8 @@ namespace :gem do
|
|
43
44
|
task :gemspec do
|
44
45
|
spec_string = GEM_SPEC.to_ruby
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
rescue
|
49
|
-
abort "unsafe gemspec: #{$!}"
|
50
|
-
else
|
51
|
-
File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
|
52
|
-
file.write spec_string
|
53
|
-
end
|
47
|
+
File.open("#{GEM_SPEC.name}.gemspec", "w") do |file|
|
48
|
+
file.write spec_string
|
54
49
|
end
|
55
50
|
end
|
56
51
|
|
data/uuidtools.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: uuidtools 3.0.0 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "uuidtools".freeze
|
6
|
+
s.version = "3.0.0".freeze
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
|
+
s.require_paths = ["lib".freeze]
|
10
|
+
s.authors = ["Bob Aman".freeze]
|
11
|
+
s.date = "2025-03-09"
|
12
|
+
s.description = "A simple universally unique ID generation library.\n".freeze
|
13
|
+
s.email = "bob@sporkmonger.com".freeze
|
14
|
+
s.extra_rdoc_files = ["README.md".freeze]
|
15
|
+
s.files = ["CHANGELOG".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "lib".freeze, "lib/compat".freeze, "lib/compat/securerandom.rb".freeze, "lib/uuidtools".freeze, "lib/uuidtools.rb".freeze, "lib/uuidtools/version.rb".freeze, "spec".freeze, "spec/spec.opts".freeze, "spec/spec_helper.rb".freeze, "spec/uuidtools".freeze, "spec/uuidtools/mac_address_spec.rb".freeze, "spec/uuidtools/utility_spec.rb".freeze, "spec/uuidtools/uuid_creation_spec.rb".freeze, "spec/uuidtools/uuid_parsing_spec.rb".freeze, "tasks".freeze, "tasks/benchmark.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze, "tasks/metrics.rake".freeze, "tasks/rspec.rake".freeze, "tasks/yard.rake".freeze, "uuidtools.gemspec".freeze, "website".freeze, "website/index.html".freeze]
|
16
|
+
s.homepage = "https://github.com/sporkmonger/uuidtools".freeze
|
17
|
+
s.licenses = ["Apache-2.0".freeze]
|
18
|
+
s.rdoc_options = ["--main".freeze, "README.md".freeze]
|
19
|
+
s.rubygems_version = "3.6.3".freeze
|
20
|
+
s.summary = "UUID generator".freeze
|
21
|
+
|
22
|
+
s.specification_version = 4
|
23
|
+
|
24
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0.7.3".freeze])
|
25
|
+
s.add_development_dependency(%q<rspec>.freeze, [">= 2.9.0".freeze])
|
26
|
+
s.add_development_dependency(%q<yard>.freeze, [">= 0.8.2".freeze])
|
27
|
+
s.add_development_dependency(%q<launchy>.freeze, [">= 2.0.0".freeze])
|
28
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uuidtools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Aman
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-03-09 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rake
|
@@ -66,8 +65,9 @@ dependencies:
|
|
66
65
|
- - ">="
|
67
66
|
- !ruby/object:Gem::Version
|
68
67
|
version: 2.0.0
|
69
|
-
description:
|
70
|
-
|
68
|
+
description: 'A simple universally unique ID generation library.
|
69
|
+
|
70
|
+
'
|
71
71
|
email: bob@sporkmonger.com
|
72
72
|
executables: []
|
73
73
|
extensions: []
|
@@ -93,11 +93,12 @@ files:
|
|
93
93
|
- tasks/metrics.rake
|
94
94
|
- tasks/rspec.rake
|
95
95
|
- tasks/yard.rake
|
96
|
+
- uuidtools.gemspec
|
96
97
|
- website/index.html
|
97
98
|
homepage: https://github.com/sporkmonger/uuidtools
|
98
|
-
licenses:
|
99
|
+
licenses:
|
100
|
+
- Apache-2.0
|
99
101
|
metadata: {}
|
100
|
-
post_install_message:
|
101
102
|
rdoc_options:
|
102
103
|
- "--main"
|
103
104
|
- README.md
|
@@ -114,9 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
115
|
- !ruby/object:Gem::Version
|
115
116
|
version: '0'
|
116
117
|
requirements: []
|
117
|
-
|
118
|
-
rubygems_version: 2.2.2
|
119
|
-
signing_key:
|
118
|
+
rubygems_version: 3.6.3
|
120
119
|
specification_version: 4
|
121
120
|
summary: UUID generator
|
122
121
|
test_files: []
|