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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ebf635496c48e173f29b09b4719846a83ab15d19
4
- data.tar.gz: cdf833d1f98797978853ee0d700277704ec9ad86
2
+ SHA256:
3
+ metadata.gz: 3a3a7b4cd84917d78bc44482023ea1e337b407b176dda81fc097f1617bfb1545
4
+ data.tar.gz: 9af85de9393ea8752ee5cba3feff96f2ba7994dd4092bea6dcae5bdb6229c12f
5
5
  SHA512:
6
- metadata.gz: 33c70bffe56bd16152da53299f283067ec0087070a3b4a94347a01d30bceada03b879e3cf2df697e168deff94789c5c69933641f77707764d187debf52bad7e7
7
- data.tar.gz: dd36f05b2ec9f696c6c1a1c413df01f0372e504be3c09d4db77340c7db3bd68253e326b835913ef2cf9f35fd534ccb777ea00d043b47a272da46a461607bc3fe
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
+ [![Build Status](https://secure.travis-ci.org/sporkmonger/uuidtools.svg)](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
- [![Build Status](https://secure.travis-ci.org/sporkmonger/uuidtools.png)](http://travis-ci.org/sporkmonger/uuidtools)
11
- [![Dependency Status](https://gemnasium.com/sporkmonger/uuidtools.png)](https://gemnasium.com/sporkmonger/uuidtools)
12
- [![Gittip Donate](http://img.shields.io/gittip/sporkmonger.png)](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
@@ -20,9 +20,9 @@
20
20
  unless defined? UUIDTools::VERSION
21
21
  module UUIDTools
22
22
  module VERSION #:nodoc:
23
- MAJOR = 2
24
- MINOR = 1
25
- TINY = 5
23
+ MAJOR = 3
24
+ MINOR = 0
25
+ TINY = 0
26
26
 
27
27
  STRING = [MAJOR, MINOR, TINY].join('.')
28
28
  end
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
- for i in 0..5
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
- time_low = (integer >> 96) & 0xFFFFFFFF
184
- time_mid = (integer >> 80) & 0xFFFF
185
- time_hi_and_version = (integer >> 64) & 0xFFFF
186
- clock_seq_hi_and_reserved = (integer >> 56) & 0xFF
187
- clock_seq_low = (integer >> 48) & 0xFF
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 0..5
190
- nodes << ((integer >> (40 - (i * 8))) & 0xFF)
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
- clock_seq_hi_and_reserved, clock_seq_low, nodes)
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
- return self.parse_raw(self.convert_int_to_byte_string(uuid_int, 16))
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(uuid_hexdigest)
209
- unless uuid_hexdigest.kind_of?(String)
253
+ def self.parse_hexdigest(uuid_hex)
254
+ unless uuid_hex.kind_of?(String)
210
255
  raise ArgumentError,
211
- "Expected String, got #{uuid_hexdigest.class.name} instead."
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
- return self.parse_int(uuid_hexdigest.to_i(16))
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
- for i in 0..5
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
- if [0b000, 0b100, 0b110, 0b111].include?(self.variant) &&
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
- for i in 0..5
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
- for i in 0..5
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
- for i in 0..5
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
- os_class = :windows
585
+ :windows
534
586
  elsif os_platform =~ /solaris/i
535
- os_class = :solaris
587
+ :solaris
536
588
  elsif os_platform =~ /netbsd/i
537
- os_class = :netbsd
589
+ :netbsd
538
590
  elsif os_platform =~ /openbsd/i
539
- os_class = :openbsd
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 (path == "" && File.exist?(UUID.ifconfig_path_default))
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 (path == "" && File.exist?(UUID.ip_path_default))
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
- # if it does not exist, try the ip command
580
- if ifconfig_path == nil
581
- ifconfig_path = "#{UUID.ip_path} addr list"
582
- # all makes no sense when using ip(1)
583
- all = nil
584
- end
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
- @@mac_address = UUID.first_mac `ipconfig /all`
706
+ ipconfig_output = UUID.ipconfig(:all)
707
+ @@mac_address = UUID.first_mac ipconfig_output
631
708
  rescue
632
709
  end
633
- else # linux, bsd, macos, solaris
634
- @@mac_address = UUID.first_mac(UUID.ifconfig(:all))
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
- for i in 0..(size - 1)
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
- for i in 0..(size - 1)
717
- ordinal = (byte_string[i].respond_to?(:ord) ?
718
- byte_string[i].ord : byte_string[i])
719
- integer += (ordinal << (((size - 1) - i) * 8))
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("^([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-" +
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 ifconfig() to return the windows sample
264
- allow(UUIDTools::UUID).to receive(:ifconfig) { samples[:windows] }
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(lambda do
58
+ expect do
58
59
  UUIDTools::UUID.new(-1, 0, 0, 0, 0, [0, 0, 0, 0, 0, 0])
59
- end).to raise_error(ArgumentError)
60
- expect(lambda do
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).to raise_error(ArgumentError)
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(lambda do
67
+ expect do
67
68
  UUIDTools::UUID.new(0, -1, 0, 0, 0, [0, 0, 0, 0, 0, 0])
68
- end).to raise_error(ArgumentError)
69
- expect(lambda do
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).to raise_error(ArgumentError)
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(lambda do
76
+ expect do
76
77
  UUIDTools::UUID.new(0, 0, -1, 0, 0, [0, 0, 0, 0, 0, 0])
77
- end).to raise_error(ArgumentError)
78
- expect(lambda do
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).to raise_error(ArgumentError)
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(lambda do
85
+ expect do
85
86
  UUIDTools::UUID.new(0, 0, 0, -1, 0, [0, 0, 0, 0, 0, 0])
86
- end).to raise_error(ArgumentError)
87
- expect(lambda do
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).to raise_error(ArgumentError)
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(lambda do
94
+ expect do
94
95
  UUIDTools::UUID.new(0, 0, 0, 0, -1, [0, 0, 0, 0, 0, 0])
95
- end).to raise_error(ArgumentError)
96
- expect(lambda do
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).to raise_error(ArgumentError)
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(lambda do
103
+ expect do
103
104
  UUIDTools::UUID.new(0, 0, 0, 0, 0, :bogus)
104
- end).to raise_error(TypeError)
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(lambda do
109
+ expect do
109
110
  UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0])
110
- end).to raise_error(ArgumentError)
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(lambda do
115
+ expect do
115
116
  UUIDTools::UUID.new(0, 0, 0, 0, 0, [0, 0, 0, 0, 0, 256])
116
- end).to raise_error(ArgumentError)
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(lambda do
121
+ expect do
121
122
  UUIDTools::UUID.parse(:bogus)
122
- end).to raise_error(TypeError)
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(lambda do
127
+ expect do
127
128
  UUIDTools::UUID.parse_raw(:bogus)
128
- end).to raise_error(TypeError)
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(Fixnum)
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
- # Version 1
6
- result = Benchmark.measure do
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
- # Version 3
14
- result = Benchmark.measure do
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
- # Version 4
23
- result = Benchmark.measure do
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
- # Version 5
31
- result = Benchmark.measure do
32
- 10000.times do
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
- puts "#{(10000.0 / result.real)} version 5 per second."
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
- begin
47
- Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
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: 2.1.5
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: 2014-08-12 00:00:00.000000000 Z
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
- A simple universally unique ID generation library.
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
- rubyforge_project:
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: []