uuidtools 1.0.3 → 1.0.4

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,5 +1,13 @@
1
+ == UUIDTools 1.0.4
2
+ * calculates random node id with multicast bit if there is no MAC address
3
+ * uses RSpec instead of Test::Unit
4
+ * works in Ruby 1.9
5
+ * cleaned up some code
6
+ * removed deprecated methods
7
+ * changed version constant
8
+ * new gem file structure
1
9
  == UUIDTools 1.0.3
2
- * imrpoved code for obtaining a MAC address within JRuby
10
+ * improved code for obtaining a MAC address within JRuby
3
11
  == UUIDTools 1.0.2
4
12
  * improved code for obtaining a MAC address for Solaris and OpenBSD
5
13
  * added hash and eql? methods
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ UUIDTools, Copyright (c) 2005-2008 Bob Aman
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.
@@ -0,0 +1,44 @@
1
+ lib_dir = File.expand_path(File.join(File.dirname(__FILE__), "lib"))
2
+ $:.unshift(lib_dir)
3
+ $:.uniq!
4
+
5
+ require 'rubygems'
6
+ require 'rake'
7
+ require 'rake/testtask'
8
+ require 'rake/rdoctask'
9
+ require 'rake/packagetask'
10
+ require 'rake/gempackagetask'
11
+ require 'rake/contrib/rubyforgepublisher'
12
+ require 'spec/rake/spectask'
13
+
14
+ require File.join(File.dirname(__FILE__), 'lib/uuidtools', 'version')
15
+
16
+ PKG_DISPLAY_NAME = 'UUIDTools'
17
+ PKG_NAME = PKG_DISPLAY_NAME.downcase
18
+ PKG_VERSION = UUID::VERSION::STRING
19
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
20
+
21
+ RELEASE_NAME = "REL #{PKG_VERSION}"
22
+
23
+ RUBY_FORGE_PROJECT = PKG_NAME
24
+ RUBY_FORGE_USER = "sporkmonger"
25
+ RUBY_FORGE_PATH = "/var/www/gforge-projects/#{RUBY_FORGE_PROJECT}"
26
+ RUBY_FORGE_URL = "http://#{RUBY_FORGE_PROJECT}.rubyforge.org/"
27
+
28
+ PKG_SUMMARY = "UUID generator"
29
+ PKG_DESCRIPTION = <<-TEXT
30
+ A simple universally unique ID generation library.
31
+ TEXT
32
+
33
+ PKG_FILES = FileList[
34
+ "lib/**/*", "spec/**/*", "vendor/**/*",
35
+ "tasks/**/*", "website/**/*",
36
+ "[A-Z]*", "Rakefile"
37
+ ].exclude(/database\.yml/).exclude(/[_\.]git$/)
38
+
39
+ task :default => "spec:verify"
40
+
41
+ WINDOWS = (RUBY_PLATFORM =~ /mswin|win32|mingw|bccwin|cygwin/) rescue false
42
+ SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
43
+
44
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005-2008 Robert Aman
2
+ # UUIDTools, Copyright (c) 2005-2008 Bob Aman
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -31,65 +31,6 @@ require 'digest/md5'
31
31
 
32
32
  require 'uuidtools/version'
33
33
 
34
- # Backwards compatibility with old method of versioning.
35
- UUID_TOOLS_VERSION = UUID::UUID_TOOLS_VERSION::STRING
36
-
37
- # Because it's impossible to hype a UUID generator on its genuine merits,
38
- # I give you... Really bad ASCII art in the comments:
39
- #
40
- #
41
- # \
42
- # /
43
- # +
44
- # ]
45
- # ]
46
- # |
47
- # /
48
- # Mp___
49
- # `~0NNp,
50
- # __ggM'
51
- # g0M~"`
52
- # ]0M*-
53
- #
54
- # ___
55
- # _g000M00g,
56
- # j0M~ ~M&
57
- # j0M" ~N,
58
- # j0P M&
59
- # jM 1
60
- # j0 ]1
61
- # .0P 0,
62
- # 00' M&
63
- # 0M ]0L
64
- # ]0f ___ M0
65
- # M0NN0M00MMM~"'M 0&
66
- # `~ ~0 ]0,
67
- # ]M ]0&
68
- # M& M0,
69
- # ____gp_ M& M0_
70
- # __p0MPM8MM&_ M/ ^0&_
71
- # gN"` M0N_j0, MM&__
72
- # _gF `~M0P` __ M00g
73
- # g0' gM0&, ~M0&
74
- # _pM` 0, ]M1 "00&
75
- # _00 /g1MMgj01 ]0MI
76
- # _0F t"M,7MMM 00I
77
- # g0' _ N&j& 40'
78
- # g0' _p0Mq_ ' N0QQNM#g,
79
- # 0' _g0000000g__ ~M@MMM000g
80
- # f _jM00@` ~M0000Mgppg, "P00&
81
- # | g000~ `~M000000&_ ~0&
82
- # ]M _M00F "00MM` ~#&
83
- # `0L m000F #E "0f
84
- # 9r j000M` 40, 00
85
- # ]0g_ j00M` ^M0MNggp#gqpg M0&
86
- # ~MPM0f ~M000000000g_ ,_ygg&M00f
87
- # `~~~M00000000000000
88
- # `M0000000000f
89
- # ~@@@MF~`
90
- #
91
- #
92
-
93
34
  #= uuidtools.rb
94
35
  #
95
36
  # UUIDTools was designed to be a simple library for generating any
@@ -106,13 +47,12 @@ UUID_TOOLS_VERSION = UUID::UUID_TOOLS_VERSION::STRING
106
47
  # UUID.random_create
107
48
  # => #<UUID:0x19013a UUID:984265dc-4200-4f02-ae70-fe4f48964159>
108
49
  class UUID
109
- @@mac_address = nil
110
50
  @@last_timestamp = nil
111
51
  @@last_node_id = nil
112
52
  @@last_clock_sequence = nil
113
53
  @@state_file = nil
114
54
  @@mutex = Mutex.new
115
-
55
+
116
56
  def initialize(time_low, time_mid, time_hi_and_version,
117
57
  clock_seq_hi_and_reserved, clock_seq_low, nodes)
118
58
  unless time_low >= 0 && time_low < 4294967296
@@ -141,7 +81,7 @@ class UUID
141
81
  unless nodes.respond_to? :size
142
82
  raise ArgumentError,
143
83
  "Expected nodes to respond to :size."
144
- end
84
+ end
145
85
  unless nodes.size == 6
146
86
  raise ArgumentError,
147
87
  "Expected nodes to have size of 6."
@@ -160,14 +100,14 @@ class UUID
160
100
  @clock_seq_low = clock_seq_low
161
101
  @nodes = nodes
162
102
  end
163
-
103
+
164
104
  attr_accessor :time_low
165
105
  attr_accessor :time_mid
166
106
  attr_accessor :time_hi_and_version
167
107
  attr_accessor :clock_seq_hi_and_reserved
168
108
  attr_accessor :clock_seq_low
169
109
  attr_accessor :nodes
170
-
110
+
171
111
  # Parses a UUID from a string.
172
112
  def self.parse(uuid_string)
173
113
  unless uuid_string.kind_of? String
@@ -214,7 +154,7 @@ class UUID
214
154
 
215
155
  # Creates a UUID from a random value.
216
156
  def self.random_create()
217
- new_uuid = self.parse_raw(self.random_128)
157
+ new_uuid = self.parse_raw(self.random_bits)
218
158
  new_uuid.time_hi_and_version &= 0x0FFF
219
159
  new_uuid.time_hi_and_version |= (4 << 12)
220
160
  new_uuid.clock_seq_hi_and_reserved &= 0x3F
@@ -236,26 +176,34 @@ class UUID
236
176
  # Convert to 100 nanosecond blocks
237
177
  gmt_timestamp_100_nanoseconds = (gmt_timestamp.tv_sec * 10000000) +
238
178
  (gmt_timestamp.tv_usec * 10) + 0x01B21DD213814000
239
- mac_address = self.get_mac_address
240
- if mac_address == nil || mac_address == ""
241
- raise StandardError,
242
- "MAC address could not be autodetected. " +
243
- "Set the MAC address manually."
244
- end
245
- nodes = mac_address.split(":").collect do |octet|
246
- octet.to_i(16)
247
- end
179
+ mac_address = self.mac_address
248
180
  node_id = 0
181
+ if mac_address != nil
182
+ nodes = mac_address.split(":").collect do |octet|
183
+ octet.to_i(16)
184
+ end
185
+ else
186
+ nodes = self.random_bits(48).split("").map do |chr|
187
+ if chr.respond_to?(:ord)
188
+ # Ruby 1.9
189
+ chr.ord
190
+ else
191
+ # Ruby 1.8
192
+ chr.sum(8)
193
+ end
194
+ end
195
+ nodes[0] |= 0b00000001
196
+ end
249
197
  for i in 0..5
250
198
  node_id += (nodes[i] << (40 - (i * 8)))
251
199
  end
252
200
  clock_sequence = @@last_clock_sequence
253
201
  if clock_sequence.nil?
254
- clock_sequence = self.convert_byte_string_to_int(self.random_128)
202
+ clock_sequence = self.convert_byte_string_to_int(self.random_bits)
255
203
  end
256
204
  if @@last_node_id != nil && @@last_node_id != node_id
257
205
  # The node id has changed. Change the clock id.
258
- clock_sequence = self.convert_byte_string_to_int(self.random_128)
206
+ clock_sequence = self.convert_byte_string_to_int(self.random_bits)
259
207
  elsif @@last_timestamp != nil &&
260
208
  gmt_timestamp_100_nanoseconds <= @@last_timestamp
261
209
  clock_sequence = clock_sequence + 1
@@ -271,7 +219,7 @@ class UUID
271
219
  clock_seq_low = clock_sequence & 0xFF;
272
220
  clock_seq_hi_and_reserved = (clock_sequence & 0x3F00) >> 8
273
221
  clock_seq_hi_and_reserved |= 0x80
274
-
222
+
275
223
  return self.new(time_low, time_mid, time_hi_and_version,
276
224
  clock_seq_hi_and_reserved, clock_seq_low, nodes)
277
225
  end
@@ -281,12 +229,12 @@ class UUID
281
229
  def self.md5_create(namespace, name)
282
230
  return self.create_from_hash(Digest::MD5, namespace, name)
283
231
  end
284
-
232
+
285
233
  # Creates a UUID using the SHA1 hash. (Version 5)
286
234
  def self.sha1_create(namespace, name)
287
235
  return self.create_from_hash(Digest::SHA1, namespace, name)
288
236
  end
289
-
237
+
290
238
  # This method applies only to version 1 UUIDs.
291
239
  # Checks if the node ID was generated from a random number
292
240
  # or from an IEEE 802 address (MAC address).
@@ -297,7 +245,7 @@ class UUID
297
245
  return false if self.version != 1
298
246
  return ((self.nodes.first & 0x01) == 1)
299
247
  end
300
-
248
+
301
249
  # Returns true if this UUID is the
302
250
  # nil UUID (00000000-0000-0000-0000-000000000000).
303
251
  def nil_uuid?
@@ -311,7 +259,7 @@ class UUID
311
259
  end
312
260
  return true
313
261
  end
314
-
262
+
315
263
  # Returns the UUID version type.
316
264
  # Possible values:
317
265
  # 1 - Time-based with unique or random host identifier
@@ -341,7 +289,7 @@ class UUID
341
289
  end
342
290
  return (result >> 6)
343
291
  end
344
-
292
+
345
293
  # Returns true if this UUID is valid.
346
294
  def valid?
347
295
  if [0b000, 0b100, 0b110, 0b111].include?(self.variant) &&
@@ -351,7 +299,7 @@ class UUID
351
299
  return false
352
300
  end
353
301
  end
354
-
302
+
355
303
  # Returns the IEEE 802 address used to generate this UUID or
356
304
  # nil if a MAC address was not used.
357
305
  def mac_address
@@ -361,7 +309,7 @@ class UUID
361
309
  sprintf("%2.2x", node)
362
310
  end).join(":")
363
311
  end
364
-
312
+
365
313
  # Returns the timestamp used to generate this UUID
366
314
  def timestamp
367
315
  return nil if self.version != 1
@@ -373,7 +321,7 @@ class UUID
373
321
  return Time.at(
374
322
  (gmt_timestamp_100_nanoseconds - 0x01B21DD213814000) / 10000000.0)
375
323
  end
376
-
324
+
377
325
  # Compares two UUIDs lexically
378
326
  def <=>(other_uuid)
379
327
  check = self.time_low <=> other_uuid.time_low
@@ -397,22 +345,22 @@ class UUID
397
345
  end
398
346
  return 0
399
347
  end
400
-
348
+
401
349
  # Returns a representation of the object's state
402
350
  def inspect
403
351
  return "#<UUID:0x#{self.object_id.to_s(16)} UUID:#{self.to_s}>"
404
352
  end
405
-
353
+
406
354
  # Returns the hex digest of the UUID object.
407
355
  def hexdigest
408
356
  return self.to_i.to_s(16)
409
357
  end
410
-
358
+
411
359
  # Returns the raw bytes that represent this UUID.
412
360
  def raw
413
361
  return self.class.convert_int_to_byte_string(self.to_i, 16)
414
362
  end
415
-
363
+
416
364
  # Returns a string representation for this UUID.
417
365
  def to_s
418
366
  result = sprintf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", @time_low, @time_mid,
@@ -422,7 +370,7 @@ class UUID
422
370
  end
423
371
  return result.downcase
424
372
  end
425
-
373
+
426
374
  # Returns an integer representation for this UUID.
427
375
  def to_i
428
376
  bytes = (time_low << 96) + (time_mid << 80) +
@@ -448,34 +396,11 @@ class UUID
448
396
  def eql?(other)
449
397
  return (self <=> other) == 0
450
398
  end
451
-
452
- def self.create_from_hash(hash_class, namespace, name) #:nodoc:
453
- if hash_class == Digest::MD5
454
- version = 3
455
- elsif hash_class == Digest::SHA1
456
- version = 5
457
- else
458
- raise ArgumentError,
459
- "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
460
- end
461
- hash = hash_class.new
462
- hash.update(namespace.raw)
463
- hash.update(name)
464
- hash_string = hash.to_s[0..31]
465
- new_uuid = self.parse("#{hash_string[0..7]}-#{hash_string[8..11]}-" +
466
- "#{hash_string[12..15]}-#{hash_string[16..19]}-#{hash_string[20..31]}")
467
-
468
- new_uuid.time_hi_and_version &= 0x0FFF
469
- new_uuid.time_hi_and_version |= (version << 12)
470
- new_uuid.clock_seq_hi_and_reserved &= 0x3F
471
- new_uuid.clock_seq_hi_and_reserved |= 0x80
472
- return new_uuid
473
- end
474
399
 
475
400
  # Returns the MAC address of the current computer's network card.
476
401
  # Returns nil if a MAC address could not be found.
477
402
  def self.mac_address #:nodoc:
478
- if @@mac_address.nil?
403
+ if !defined?(@@mac_address)
479
404
  require 'rbconfig'
480
405
  os_platform = Config::CONFIG['target_os']
481
406
  if os_platform =~ /win/ && !(os_platform =~ /darwin/)
@@ -485,19 +410,19 @@ class UUID
485
410
  end
486
411
  if os_platform =~ /solaris/
487
412
  begin
488
- ifconfig_output =
489
- (script_in_path ? `ifconfig -a` : `/sbin/ifconfig -a`)
490
- ip_addresses = ifconfig_output.scan(
491
- /inet\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
492
- ip = ip_addresses.find {|addr| addr[0] != '127.0.0.1'}[0]
493
- @@mac_address = `/usr/sbin/arp #{ip}`.split(' ')[3]
413
+ ifconfig_output =
414
+ (script_in_path ? `ifconfig -a` : `/sbin/ifconfig -a`)
415
+ ip_addresses = ifconfig_output.scan(
416
+ /inet\s?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/)
417
+ ip = ip_addresses.find {|addr| addr[0] != '127.0.0.1'}[0]
418
+ @@mac_address = `/usr/sbin/arp #{ip}`.split(' ')[3]
494
419
  rescue Exception
495
420
  end
496
421
  if @@mac_address == "" || @@mac_address == nil
497
422
  begin
498
- ifconfig_output =
499
- (script_in_path ?
500
- `ifconfig -a` : `/sbin/ifconfig -a`).split(' ')
423
+ ifconfig_output =
424
+ (script_in_path ?
425
+ `ifconfig -a` : `/sbin/ifconfig -a`).split(' ')
501
426
  index = ifconfig_output.index("inet") + 1
502
427
  ip = ifconfig_output[index]
503
428
  @@mac_address = `arp #{ip}`.split(' ')[3]
@@ -594,18 +519,43 @@ class UUID
594
519
  end
595
520
  return @@mac_address
596
521
  end
597
- class <<self
598
- alias_method :get_mac_address, :mac_address
599
- end
600
-
522
+
601
523
  # Allows users to set the MAC address manually in cases where the MAC
602
524
  # address cannot be obtained programatically.
603
525
  def self.mac_address=(new_mac_address)
604
526
  @@mac_address = new_mac_address
605
527
  end
606
-
607
- # 128 bits of unpredictable data.
608
- def self.random_128 #:nodoc:
528
+
529
+ protected
530
+ # Creates a new UUID from a SHA1 or MD5 hash
531
+ def self.create_from_hash(hash_class, namespace, name) #:nodoc:
532
+ if hash_class == Digest::MD5
533
+ version = 3
534
+ elsif hash_class == Digest::SHA1
535
+ version = 5
536
+ else
537
+ raise ArgumentError,
538
+ "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
539
+ end
540
+ hash = hash_class.new
541
+ hash.update(namespace.raw)
542
+ hash.update(name)
543
+ hash_string = hash.to_s[0..31]
544
+ new_uuid = self.parse("#{hash_string[0..7]}-#{hash_string[8..11]}-" +
545
+ "#{hash_string[12..15]}-#{hash_string[16..19]}-#{hash_string[20..31]}")
546
+
547
+ new_uuid.time_hi_and_version &= 0x0FFF
548
+ new_uuid.time_hi_and_version |= (version << 12)
549
+ new_uuid.clock_seq_hi_and_reserved &= 0x3F
550
+ new_uuid.clock_seq_hi_and_reserved |= 0x80
551
+ return new_uuid
552
+ end
553
+
554
+ # N bits of unpredictable data.
555
+ def self.random_bits(size=128) #:nodoc:
556
+ if 128 % 16 != 0
557
+ raise ArgumentError, "Value must be divisible by 16."
558
+ end
609
559
  if !defined?(@random_device) || @random_device == nil
610
560
  begin
611
561
  @random_device = nil
@@ -618,12 +568,12 @@ class UUID
618
568
  end
619
569
  end
620
570
  begin
621
- return @random_device.read(16) if @random_device != nil
571
+ return @random_device.read(size / 8) if @random_device != nil
622
572
  rescue Exception
623
573
  end
624
- return (1..8).to_a.map { rand(0x10000) }.pack("n8")
574
+ return (1..(size / 16)).to_a.map { rand(0x10000) }.pack("n#{size / 16}")
625
575
  end
626
-
576
+
627
577
  def self.convert_int_to_byte_string(integer, size) #:nodoc:
628
578
  byte_string = ""
629
579
  for i in 0..(size - 1)
@@ -636,7 +586,13 @@ class UUID
636
586
  integer = 0
637
587
  size = byte_string.size
638
588
  for i in 0..(size - 1)
639
- integer += (byte_string[i] << (((size - 1) - i) * 8))
589
+ if byte_string[i].respond_to?(:ord)
590
+ # Ruby 1.9
591
+ integer += (byte_string[i].ord << (((size - 1) - i) * 8))
592
+ else
593
+ # Ruby 1.8
594
+ integer += (byte_string[i] << (((size - 1) - i) * 8))
595
+ end
640
596
  end
641
597
  return integer
642
598
  end