Class: SimpleUUID::UUID

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/simple_uuid.rb

Overview

UUID format version 1, as specified in RFC 4122, with jitter in place of the mac address and sequence counter.

Defined Under Namespace

Classes: InvalidVersion

Constant Summary collapse

GREGORIAN_EPOCH_OFFSET =

Oct 15, 1582

0x01B2_1DD2_1381_4000
VARIANT =
0b1000_0000_0000_0000

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bytes = nil) ⇒ UUID

Returns a new instance of UUID.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/simple_uuid.rb', line 23

def initialize(bytes = nil)
  case bytes
  when self.class # UUID
    @bytes = bytes.to_s
  when String
    case bytes.size
    when 16 # Raw byte array
      @bytes = bytes
    when 36 # Human-readable UUID representation; inverse of #to_guid
      elements = bytes.split("-")
      raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (malformed UUID representation)" if elements.size != 5
      @bytes = [elements.join].pack('H32')
    else
      raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (invalid bytecount)"
    end

  when Integer
    raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (integer out of range)" if bytes < 0 or bytes > 2**128
    @bytes = [
      (bytes >> 96) & 0xFFFF_FFFF,
      (bytes >> 64) & 0xFFFF_FFFF,
      (bytes >> 32) & 0xFFFF_FFFF,
      bytes & 0xFFFF_FFFF
    ].pack("NNNN")

  when NilClass, Time
    time = (bytes || Time).stamp * 10 + GREGORIAN_EPOCH_OFFSET
    # See http://github.com/spectra/ruby-uuid/
    @bytes = [
      time & 0xFFFF_FFFF,
      time >> 32,
      ((time >> 48) & 0x0FFF) | 0x1000,
      # Top 3 bytes reserved
      rand(2**13) | VARIANT,
      rand(2**16),
      rand(2**32)
    ].pack("NnnnnN")

  else
    raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (unknown source class)"
  end
end

Class Method Details

.to_time(bytes) ⇒ Object

Given raw bytes, return a time object



131
132
133
134
# File 'lib/simple_uuid.rb', line 131

def self.to_time(bytes)
  usecs = total_usecs(bytes)
  Time.at(usecs / 1_000_000, usecs % 1_000_000)
end

.total_usecs(bytes) ⇒ Object

Given raw bytes, return the total_usecs



142
143
144
145
# File 'lib/simple_uuid.rb', line 142

def self.total_usecs(bytes)
  elements = bytes.unpack("Nnn")
  (elements[0] + (elements[1] << 32) + ((elements[2] & 0x0FFF) << 48) - GREGORIAN_EPOCH_OFFSET) / 10
end

Instance Method Details

#<=>(other) ⇒ Object



99
100
101
# File 'lib/simple_uuid.rb', line 99

def <=>(other)
  total_usecs <=> other.send(:total_usecs)
end

#==(other) ⇒ Object



103
104
105
# File 'lib/simple_uuid.rb', line 103

def ==(other)
  to_s == other.to_s
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


126
127
128
# File 'lib/simple_uuid.rb', line 126

def eql?(other)
  other.respond_to?(:bytes) && bytes == other.bytes
end

#hashObject



122
123
124
# File 'lib/simple_uuid.rb', line 122

def hash
  @bytes.hash
end

#inspect(long = false) ⇒ Object



107
108
109
110
111
112
113
114
115
# File 'lib/simple_uuid.rb', line 107

def inspect(long = false)
  "<UUID##{object_id} time: #{
    to_time.inspect
  }, usecs: #{
    usecs
  } jitter: #{
    @bytes.unpack('QQ')[1]
  }" + (long ? ", version: #{version}, variant: #{variant}, guid: #{to_guid}>" :  ">")
end

#secondsObject



91
92
93
# File 'lib/simple_uuid.rb', line 91

def seconds
  total_usecs / 1_000_000
end

#to_guidObject



84
85
86
87
88
89
# File 'lib/simple_uuid.rb', line 84

def to_guid
  elements = @bytes.unpack("NnnCCa6")
  node = elements[-1].unpack('C*')
  elements[-1] = '%02x%02x%02x%02x%02x%02x' % node
  "%08x-%04x-%04x-%02x%02x-%s" % elements
end

#to_iObject



66
67
68
69
70
71
72
# File 'lib/simple_uuid.rb', line 66

def to_i
  ints = @bytes.unpack("NNNN")
  (ints[0] << 96) +
  (ints[1] << 64) +
  (ints[2] << 32) +
  ints[3]
end

#to_sObject Also known as: bytes



117
118
119
# File 'lib/simple_uuid.rb', line 117

def to_s
  @bytes
end

#to_timeObject

Return a time object



137
138
139
# File 'lib/simple_uuid.rb', line 137

def to_time
  Time.at(total_usecs / 1_000_000, total_usecs % 1_000_000)
end

#usecsObject



95
96
97
# File 'lib/simple_uuid.rb', line 95

def usecs
  total_usecs % 1_000_000
end

#variantObject



80
81
82
# File 'lib/simple_uuid.rb', line 80

def variant
  @bytes.unpack('QnnN')[1] >> 13
end

#versionObject



74
75
76
77
78
# File 'lib/simple_uuid.rb', line 74

def version
  time_high = @bytes.unpack("NnnQ")[2]
  version = (time_high & 0xF000).to_s(16)[0].chr.to_i
  version > 0 and version < 6 ? version : -1
end