uuidtools 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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