uuidtools 1.0.0 → 1.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.
data/CHANGELOG CHANGED
@@ -1,9 +1,16 @@
1
+ == UUIDTools 1.0.1
2
+ * improved code for obtaining a MAC address for Solaris and NetBSD
3
+ * MAC addresses can now be set manually
4
+ * replaced random number generator, less effective on Windows, but faster
5
+ * fixed inheritance issues
6
+ * changed UUID#to_uri method to return a string instead of a URI object
7
+ * removed UUID#to_uri_string
1
8
  == UUIDTools 1.0.0
2
9
  * slight improvements to the random number generator
3
10
  * fixed issue with failing to obtain mac address in certain environments
4
11
  == UUIDTools 0.1.4
5
12
  * improved speed when generating timestamp-based uuids
6
- * fixed bug with rapid generation of timestamp uuids leading to dupicates
13
+ * fixed bug with rapid generation of timestamp uuids leading to duplicates
7
14
  * improved code for detection of mac address
8
15
  == UUIDTools 0.1.3
9
16
  * fixed issue with UUID#raw attempting to call protected class methods
@@ -21,7 +21,7 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- UUID_TOOLS_VERSION = "1.0.0"
24
+ UUID_TOOLS_VERSION = "1.0.1"
25
25
 
26
26
  $:.unshift(File.dirname(__FILE__))
27
27
 
@@ -166,7 +166,7 @@ class UUID
166
166
  attr_accessor :nodes
167
167
 
168
168
  # Parses a UUID from a string.
169
- def UUID.parse(uuid_string)
169
+ def self.parse(uuid_string)
170
170
  unless uuid_string.kind_of? String
171
171
  raise ArgumentError,
172
172
  "Expected String, got #{uuid_string.class.name} instead."
@@ -184,17 +184,17 @@ class UUID
184
184
  for i in 0..5
185
185
  nodes << uuid_components[5][(i * 2)..(i * 2) + 1].to_i(16)
186
186
  end
187
- return UUID.new(time_low, time_mid, time_hi_and_version,
187
+ return self.new(time_low, time_mid, time_hi_and_version,
188
188
  clock_seq_hi_and_reserved, clock_seq_low, nodes)
189
189
  end
190
190
 
191
191
  # Parses a UUID from a raw byte string.
192
- def UUID.parse_raw(raw_string)
192
+ def self.parse_raw(raw_string)
193
193
  unless raw_string.kind_of? String
194
194
  raise ArgumentError,
195
195
  "Expected String, got #{raw_string.class.name} instead."
196
196
  end
197
- integer = UUID.convert_byte_string_to_int(raw_string)
197
+ integer = self.convert_byte_string_to_int(raw_string)
198
198
 
199
199
  time_low = (integer >> 96) & 0xFFFFFFFF
200
200
  time_mid = (integer >> 80) & 0xFFFF
@@ -205,13 +205,13 @@ class UUID
205
205
  for i in 0..5
206
206
  nodes << ((integer >> (40 - (i * 8))) & 0xFF)
207
207
  end
208
- return UUID.new(time_low, time_mid, time_hi_and_version,
208
+ return self.new(time_low, time_mid, time_hi_and_version,
209
209
  clock_seq_hi_and_reserved, clock_seq_low, nodes)
210
210
  end
211
211
 
212
212
  # Creates a UUID from a random value.
213
- def UUID.random_create()
214
- new_uuid = UUID.parse_raw(UUID.true_random)
213
+ def self.random_create()
214
+ new_uuid = self.parse_raw(self.random_128)
215
215
  new_uuid.time_hi_and_version &= 0x0FFF
216
216
  new_uuid.time_hi_and_version |= (4 << 12)
217
217
  new_uuid.clock_seq_hi_and_reserved &= 0x3F
@@ -220,7 +220,7 @@ class UUID
220
220
  end
221
221
 
222
222
  # Creates a UUID from a timestamp.
223
- def UUID.timestamp_create(timestamp=nil)
223
+ def self.timestamp_create(timestamp=nil)
224
224
  # We need a lock here to prevent two threads from ever
225
225
  # getting the same timestamp.
226
226
  @@mutex.synchronize do
@@ -233,7 +233,7 @@ class UUID
233
233
  # Convert to 100 nanosecond blocks
234
234
  gmt_timestamp_100_nanoseconds = (gmt_timestamp.tv_sec * 10000000) +
235
235
  (gmt_timestamp.tv_usec * 10) + 0x01B21DD213814000
236
- nodes = UUID.get_mac_address.split(":").collect do |octet|
236
+ nodes = self.get_mac_address.split(":").collect do |octet|
237
237
  octet.to_i(16)
238
238
  end
239
239
  node_id = 0
@@ -242,11 +242,11 @@ class UUID
242
242
  end
243
243
  clock_sequence = @@last_clock_sequence
244
244
  if clock_sequence.nil?
245
- clock_sequence = UUID.convert_byte_string_to_int(UUID.true_random)
245
+ clock_sequence = self.convert_byte_string_to_int(self.random_128)
246
246
  end
247
247
  if @@last_node_id != nil && @@last_node_id != node_id
248
248
  # The node id has changed. Change the clock id.
249
- clock_sequence = UUID.convert_byte_string_to_int(UUID.true_random)
249
+ clock_sequence = self.convert_byte_string_to_int(self.random_128)
250
250
  elsif @@last_timestamp != nil &&
251
251
  gmt_timestamp_100_nanoseconds <= @@last_timestamp
252
252
  clock_sequence = clock_sequence + 1
@@ -263,19 +263,19 @@ class UUID
263
263
  clock_seq_hi_and_reserved = (clock_sequence & 0x3F00) >> 8
264
264
  clock_seq_hi_and_reserved |= 0x80
265
265
 
266
- return UUID.new(time_low, time_mid, time_hi_and_version,
266
+ return self.new(time_low, time_mid, time_hi_and_version,
267
267
  clock_seq_hi_and_reserved, clock_seq_low, nodes)
268
268
  end
269
269
  end
270
270
 
271
271
  # Creates a UUID using the MD5 hash. (Version 3)
272
- def UUID.md5_create(namespace, name)
273
- return UUID.create_from_hash(Digest::MD5, namespace, name)
272
+ def self.md5_create(namespace, name)
273
+ return self.create_from_hash(Digest::MD5, namespace, name)
274
274
  end
275
275
 
276
276
  # Creates a UUID using the SHA1 hash. (Version 5)
277
- def UUID.sha1_create(namespace, name)
278
- return UUID.create_from_hash(Digest::SHA1, namespace, name)
277
+ def self.sha1_create(namespace, name)
278
+ return self.create_from_hash(Digest::SHA1, namespace, name)
279
279
  end
280
280
 
281
281
  # This method applies only to version 1 UUIDs.
@@ -401,7 +401,7 @@ class UUID
401
401
 
402
402
  # Returns the raw bytes that represent this UUID.
403
403
  def raw
404
- return UUID.convert_int_to_byte_string(self.to_i, 16)
404
+ return self.class.convert_int_to_byte_string(self.to_i, 16)
405
405
  end
406
406
 
407
407
  # Returns a string representation for this UUID.
@@ -424,18 +424,13 @@ class UUID
424
424
  end
425
425
  return bytes
426
426
  end
427
-
428
- # Returns a URI for this UUID.
429
- def to_uri
430
- return URI.parse(self.to_uri_string)
431
- end
432
427
 
433
428
  # Returns a URI string for this UUID.
434
- def to_uri_string
429
+ def to_uri
435
430
  return "urn:uuid:#{self.to_s}"
436
431
  end
437
432
 
438
- def UUID.create_from_hash(hash_class, namespace, name) #:nodoc:
433
+ def self.create_from_hash(hash_class, namespace, name) #:nodoc:
439
434
  if hash_class == Digest::MD5
440
435
  version = 3
441
436
  elsif hash_class == Digest::SHA1
@@ -448,7 +443,7 @@ class UUID
448
443
  hash.update(namespace.raw)
449
444
  hash.update(name)
450
445
  hash_string = hash.to_s[0..31]
451
- new_uuid = UUID.parse("#{hash_string[0..7]}-#{hash_string[8..11]}-" +
446
+ new_uuid = self.parse("#{hash_string[0..7]}-#{hash_string[8..11]}-" +
452
447
  "#{hash_string[12..15]}-#{hash_string[16..19]}-#{hash_string[20..31]}")
453
448
 
454
449
  new_uuid.time_hi_and_version &= 0x0FFF
@@ -460,9 +455,18 @@ class UUID
460
455
 
461
456
  # Returns the MAC address of the current computer's network card.
462
457
  # Returns nil if a MAC address could not be found.
463
- def UUID.get_mac_address #:nodoc:
458
+ def self.get_mac_address #:nodoc:
464
459
  if @@mac_address.nil?
465
- if RUBY_PLATFORM =~ /win/ && !(RUBY_PLATFORM =~ /darwin/)
460
+ if RUBY_PLATFORM =~ /solaris/
461
+ begin
462
+ ifconfig_output = `/sbin/ifconfig -a`
463
+ ip_addresses = ifconfig_output.scan(
464
+ /inet\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
465
+ ip = ip_addresses.find {|addr| addr[0] != '127.0.0.1'}[0]
466
+ @@mac_address = `/usr/sbin/arp #{ip}`.split(' ')[3]
467
+ rescue Exception
468
+ end
469
+ elsif RUBY_PLATFORM =~ /win/ && !(RUBY_PLATFORM =~ /darwin/)
466
470
  begin
467
471
  ifconfig_output = `ipconfig /all`
468
472
  mac_addresses = ifconfig_output.scan(
@@ -475,11 +479,19 @@ class UUID
475
479
  else
476
480
  begin
477
481
  mac_addresses = []
478
- if File.exists?('/sbin/ifconfig')
479
- ifconfig_output =
480
- `/sbin/ifconfig 2>&1`
482
+ if RUBY_PLATFORM =~ /netbsd/
483
+ ifconfig_output = `/sbin/ifconfig -a 2>&1`
484
+ mac_addresses = ifconfig_output.scan(
485
+ Regexp.new("address\: (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
486
+ elsif File.exists?('/sbin/ifconfig')
487
+ ifconfig_output = `/sbin/ifconfig 2>&1`
481
488
  mac_addresses = ifconfig_output.scan(
482
489
  Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
490
+ if mac_addresses.size == 0
491
+ ifconfig_output = `/sbin/ifconfig -a 2>&1`
492
+ mac_addresses = ifconfig_output.scan(
493
+ Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
494
+ end
483
495
  if mac_addresses.size == 0
484
496
  ifconfig_output =
485
497
  `/sbin/ifconfig | grep HWaddr | cut -c39- 2>&1`
@@ -491,6 +503,12 @@ class UUID
491
503
  `ifconfig 2>&1`
492
504
  mac_addresses = ifconfig_output.scan(
493
505
  Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
506
+ if mac_addresses.size == 0
507
+ ifconfig_output =
508
+ `ifconfig -a 2>&1`
509
+ mac_addresses = ifconfig_output.scan(
510
+ Regexp.new("ether (#{(["[0-9a-fA-F]{2}"] * 6).join(":")})"))
511
+ end
494
512
  if mac_addresses.size == 0
495
513
  ifconfig_output =
496
514
  `ifconfig | grep HWaddr | cut -c39- 2>&1`
@@ -504,51 +522,48 @@ class UUID
504
522
  rescue
505
523
  end
506
524
  end
525
+ @@mac_address.downcase! if @@mac_address.respond_to?(:downcase!)
526
+ @@mac_address.strip! if @@mac_address.respond_to?(:strip!)
527
+ # Verify that the MAC address is in the right format.
528
+ # Nil it out if it isn't.
529
+ unless @@mac_address.respond_to?(:scan) &&
530
+ @@mac_address.scan(/#{(["[0-9a-f]{2}"] * 6).join(":")}/)
531
+ @@mac_address = nil
532
+ end
507
533
  end
508
534
  return @@mac_address
509
535
  end
536
+ class <<self
537
+ alias_method :mac_address, :get_mac_address
538
+ end
510
539
 
511
- # Returns 128 bits of highly unpredictable data.
512
- # The random number generator isn't perfect, but it's
513
- # much, much better than the built-in pseudorandom number generators.
514
- def UUID.true_random #:nodoc:
515
- require 'benchmark'
516
- hash = Digest::SHA1.new
517
- performance = Benchmark.measure do
518
- hash.update(rand.to_s)
519
- hash.update(srand.to_s)
520
- hash.update(rand.to_s)
521
- hash.update(srand.to_s)
522
- hash.update(Time.now.to_s)
523
- hash.update(rand.to_s)
524
- hash.update(self.object_id.to_s)
525
- hash.update(rand.to_s)
526
- hash.update(hash.object_id.to_s)
527
- hash.update(self.methods.inspect)
528
- hash.update($:.to_s)
540
+ # Allows users to set the MAC address manually in cases where the MAC
541
+ # address cannot be obtained programatically.
542
+ def self.mac_address=(new_mac_address)
543
+ @@mac_address = new_mac_address
544
+ end
545
+
546
+ # 128 bits of unpredictable data.
547
+ def self.random_128 #:nodoc:
548
+ if !defined?(@random_device) || @random_device == nil
529
549
  begin
530
- random_device = nil
550
+ @random_device = nil
531
551
  if File.exists? "/dev/urandom"
532
- random_device = File.open "/dev/urandom", "r"
552
+ @random_device = File.open "/dev/urandom", "r"
533
553
  elsif File.exists? "/dev/random"
534
- random_device = File.open "/dev/random", "r"
554
+ @random_device = File.open "/dev/random", "r"
535
555
  end
536
- hash.update(random_device.read(20)) if random_device != nil
537
- rescue
556
+ rescue Exception
538
557
  end
539
- begin
540
- srand(hash.to_s.to_i(16) >> 128)
541
- rescue
542
- end
543
- hash.update(rand.to_s)
544
- hash.update(UUID.true_random) if (rand(2) == 0)
545
558
  end
546
- hash.update(performance.real.to_s)
547
- hash.update(performance.inspect)
548
- return UUID.convert_int_to_byte_string(hash.to_s[4..35].to_i(16), 16)
559
+ begin
560
+ return @random_device.read(16) if @random_device != nil
561
+ rescue Exception
562
+ end
563
+ return (1..8).to_a.map { rand(0x10000) }.pack("n8")
549
564
  end
550
565
 
551
- def UUID.convert_int_to_byte_string(integer, size) #:nodoc:
566
+ def self.convert_int_to_byte_string(integer, size) #:nodoc:
552
567
  byte_string = ""
553
568
  for i in 0..(size - 1)
554
569
  byte_string << ((integer >> (((size - 1) - i) * 8)) & 0xFF)
@@ -556,7 +571,7 @@ class UUID
556
571
  return byte_string
557
572
  end
558
573
 
559
- def UUID.convert_byte_string_to_int(byte_string) #:nodoc:
574
+ def self.convert_byte_string_to_int(byte_string) #:nodoc:
560
575
  integer = 0
561
576
  size = byte_string.size
562
577
  for i in 0..(size - 1)
@@ -569,4 +584,4 @@ end
569
584
  UUID_DNS_NAMESPACE = UUID.parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
570
585
  UUID_URL_NAMESPACE = UUID.parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
571
586
  UUID_OID_NAMESPACE = UUID.parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
572
- UUID_X500_NAMESPACE = UUID.parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
587
+ UUID_X500_NAMESPACE = UUID.parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
data/rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake/gempackagetask'
7
7
  require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_NAME = 'uuidtools'
10
- PKG_VERSION = '1.0.0'
10
+ PKG_VERSION = '1.0.1'
11
11
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
12
12
 
13
13
  RELEASE_NAME = "REL #{PKG_VERSION}"
@@ -16,7 +16,7 @@ RUBY_FORGE_PROJECT = "uuidtools"
16
16
  RUBY_FORGE_USER = "vacindak"
17
17
 
18
18
  PKG_FILES = FileList[
19
- "lib/**/*", "test/**/*", "examples/**/*", "doc/**/*", "[A-Z]*", "install.rb", "rakefile"
19
+ "lib/**/*", "test/**/*", "examples/**/*", "doc/**/*", "[A-Z]*", "rakefile"
20
20
  ].exclude(/\bCVS\b|~$/).exclude(/database\.yml/)
21
21
 
22
22
  desc "Default Task"
@@ -52,7 +52,7 @@ spec = Gem::Specification.new do |s|
52
52
  s.summary = "Generation of UUIDs."
53
53
  s.description = "Implements a simple system for generating UUIDs."
54
54
 
55
- s.files = [ "rakefile", "install.rb", "README", "CHANGELOG" ]
55
+ s.files = [ "rakefile", "README", "CHANGELOG" ]
56
56
  dist_dirs.each do |dir|
57
57
  s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if do |item|
58
58
  item.include?( "\.svn" ) || item.include?( "database\.yml" )
@@ -101,6 +101,46 @@ task :lines do
101
101
  puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
102
102
  end
103
103
 
104
+ task :benchmark do
105
+ require 'lib/uuidtools'
106
+ require 'benchmark'
107
+
108
+ # Version 1
109
+ result = Benchmark.measure do
110
+ 10000.times do
111
+ UUID.timestamp_create.to_s
112
+ end
113
+ end
114
+ puts "#{(10000.0 / result.real)} version 1 per second."
115
+
116
+ # Version 3
117
+ result = Benchmark.measure do
118
+ 10000.times do
119
+ UUID.md5_create(UUID_URL_NAMESPACE,
120
+ "http://www.ietf.org/rfc/rfc4122.txt").to_s
121
+ end
122
+ end
123
+ puts "#{(10000.0 / result.real)} version 3 per second."
124
+
125
+ # Version 4
126
+ result = Benchmark.measure do
127
+ 10000.times do
128
+ UUID.random_create.to_s
129
+ end
130
+ end
131
+ puts "#{(10000.0 / result.real)} version 4 per second."
132
+
133
+ # Version 5
134
+ result = Benchmark.measure do
135
+ 10000.times do
136
+ UUID.sha1_create(UUID_URL_NAMESPACE,
137
+ "http://www.ietf.org/rfc/rfc4122.txt").to_s
138
+ end
139
+ end
140
+ puts "#{(10000.0 / result.real)} version 5 per second."
141
+
142
+ end
143
+
104
144
 
105
145
  # Publishing ------------------------------------------------------
106
146
 
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require 'uuidtools'
3
+
4
+ class MacAddressTest < Test::Unit::TestCase
5
+ def setup
6
+ end
7
+
8
+ def test_mac_address_object
9
+ mac_address = UUID.mac_address
10
+ assert_not_nil(mac_address)
11
+ assert_equal(mac_address.object_id, UUID.mac_address.object_id)
12
+ end
13
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: uuidtools
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2006-02-13 00:00:00 -05:00
6
+ version: 1.0.1
7
+ date: 2007-04-28 00:00:00 -04:00
8
8
  summary: Generation of UUIDs.
9
9
  require_paths:
10
- - lib
10
+ - lib
11
11
  email: bob@sporkmonger.com
12
12
  homepage: http://sporkmonger.com/projects/uuidtools
13
13
  rubyforge_project: uuidtools
@@ -18,31 +18,36 @@ bindir: bin
18
18
  has_rdoc: true
19
19
  required_ruby_version: !ruby/object:Gem::Version::Requirement
20
20
  requirements:
21
- -
22
- - ">"
23
- - !ruby/object:Gem::Version
24
- version: 0.0.0
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
25
24
  version:
26
25
  platform: ruby
27
26
  signing_key:
28
27
  cert_chain:
28
+ post_install_message:
29
29
  authors:
30
- - Bob Aman
30
+ - Bob Aman
31
31
  files:
32
- - rakefile
33
- - install.rb
34
- - README
35
- - CHANGELOG
36
- - lib/uuidtools.rb
37
- - test/create_test.rb
38
- - test/parse_test.rb
32
+ - rakefile
33
+ - README
34
+ - CHANGELOG
35
+ - lib/uuidtools.rb
36
+ - test/create_test.rb
37
+ - test/mac_address_test.rb
38
+ - test/parse_test.rb
39
39
  test_files: []
40
+
40
41
  rdoc_options:
41
- - "--main"
42
- - README
42
+ - --main
43
+ - README
43
44
  extra_rdoc_files:
44
- - README
45
+ - README
45
46
  executables: []
47
+
46
48
  extensions: []
49
+
47
50
  requirements: []
48
- dependencies: []
51
+
52
+ dependencies: []
53
+
data/install.rb DELETED
@@ -1,30 +0,0 @@
1
- require 'rbconfig'
2
- require 'find'
3
- require 'ftools'
4
-
5
- include Config
6
-
7
- # this was adapted from rdoc's install.rb by ways of Log4r
8
-
9
- $sitedir = CONFIG["sitelibdir"]
10
- unless $sitedir
11
- version = CONFIG["MAJOR"] + "." + CONFIG["MINOR"]
12
- $libdir = File.join(CONFIG["libdir"], "ruby", version)
13
- $sitedir = $:.find {|x| x =~ /site_ruby/ }
14
- if !$sitedir
15
- $sitedir = File.join($libdir, "site_ruby")
16
- elsif $sitedir !~ Regexp.quote(version)
17
- $sitedir = File.join($sitedir, version)
18
- end
19
- end
20
-
21
- # the acual gruntwork
22
- Dir.chdir("lib")
23
-
24
- Find.find("uuidtools.rb") { |f|
25
- if f[-3..-1] == ".rb"
26
- File::install(f, File.join($sitedir, *f.split(/\//)), 0644, true)
27
- else
28
- File::makedirs(File.join($sitedir, *f.split(/\//)))
29
- end
30
- }