Class: SimpleUUID::UUID

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(bytes = nil) ⇒ UUID

Returns a new instance of UUID.



22
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
# File 'lib/simple_uuid.rb', line 22

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

Instance Method Details

#<=>(other) ⇒ Object



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

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

#==(other) ⇒ Object



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

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

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


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

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

#hashObject



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

def hash
  @bytes.hash
end

#inspect(long = false) ⇒ Object



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

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

#secondsObject



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

def seconds
  total_usecs / 1_000_000
end

#to_guidObject



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

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



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

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



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

def to_s
  @bytes
end

#usecsObject



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

def usecs
  total_usecs % 1_000_000
end

#variantObject



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

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

#versionObject



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

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