class SimpleUUID::UUID

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

Constants

GREGORIAN_EPOCH_OFFSET
VARIANT

Public Class Methods

new(bytes = nil, opts = {}) click to toggle source
   # File lib/simple_uuid.rb
23 def initialize(bytes = nil, opts = {})
24   case bytes
25   when self.class # UUID
26     @bytes = bytes.to_s
27   when String
28     case bytes.size
29     when 16 # Raw byte array
30       @bytes = bytes.respond_to?(:force_encoding) ? bytes.force_encoding("ASCII-8BIT") : bytes
31     when 36 # Human-readable UUID representation; inverse of #to_guid
32       elements = bytes.split("-")
33       raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (malformed UUID representation)" if elements.size != 5
34       @bytes = [elements.join].pack('H32')
35     else
36       raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (invalid bytecount)"
37     end
38 
39   when Integer
40     raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (integer out of range)" if bytes < 0 or bytes > 2**128
41     @bytes = [
42       (bytes >> 96) & 0xFFFF_FFFF,
43       (bytes >> 64) & 0xFFFF_FFFF,
44       (bytes >> 32) & 0xFFFF_FFFF,
45       bytes & 0xFFFF_FFFF
46     ].pack("NNNN")
47 
48   when NilClass, Time
49     time = (bytes || Time).stamp * 10 + GREGORIAN_EPOCH_OFFSET
50     # See http://github.com/spectra/ruby-uuid/
51     byte_array = [
52       time & 0xFFFF_FFFF,
53       time >> 32,
54       ((time >> 48) & 0x0FFF) | 0x1000,
55     ]
56 
57     # Top 3 bytes reserved
58     if opts[:randomize] == false
59       byte_array += if !opts[:salt].nil?
60         clock_h, clock_l, node_h, node_l =
61           opts[:salt].to_s.unpack("CCnN")
62 
63         clock = [
64           clock_h | VARIANT,
65           clock_l
66         ].pack("n").unpack("n").first
67 
68         [ clock, node_h, node_l ]
69       else
70         [ 0 | VARIANT, 0, 0 ]
71       end
72     else
73       byte_array += [
74         rand(2**13) | VARIANT,
75         rand(2**16),
76         rand(2**32)
77       ]
78     end
79 
80     @bytes = byte_array.pack("NnnnnN")
81   else
82     raise TypeError, "Expected #{bytes.inspect} to cast to a #{self.class} (unknown source class)"
83   end
84 end
to_time(bytes) click to toggle source

Given raw bytes, return a time object

    # File lib/simple_uuid.rb
155 def self.to_time(bytes)
156   usecs = total_usecs(bytes)
157   Time.at(usecs / 1_000_000, usecs % 1_000_000)
158 end
total_usecs(bytes) click to toggle source

Given raw bytes, return the total_usecs

    # File lib/simple_uuid.rb
166 def self.total_usecs(bytes)
167   elements = bytes.unpack("Nnn")
168   (elements[0] + (elements[1] << 32) + ((elements[2] & 0x0FFF) << 48) - GREGORIAN_EPOCH_OFFSET) / 10
169 end

Public Instance Methods

<=>(other) click to toggle source
    # File lib/simple_uuid.rb
119 def <=>(other)
120   me = to_s.unpack('Nn2C*')
121   him = other.to_s.unpack('Nn2C*')
122   # swap most significant time bits to front
123   me[0], me[2], him[0], him[2] = me[2], me[0], him[2], him[0]
124   me.zip(him) do |m, h|
125     comp = m <=> h
126     return comp if comp != 0
127   end
128   return 0
129 end
bytes()
Alias for: to_s
eql?(other) click to toggle source
    # File lib/simple_uuid.rb
150 def eql?(other)
151   other.respond_to?(:bytes) && bytes == other.bytes
152 end
hash() click to toggle source
    # File lib/simple_uuid.rb
146 def hash
147   @bytes.hash
148 end
inspect(long = false) click to toggle source
    # File lib/simple_uuid.rb
131 def inspect(long = false)
132   "<UUID##{object_id} time: #{
133     to_time.inspect
134   }, usecs: #{
135     usecs
136   } jitter: #{
137     @bytes.unpack('QQ')[1]
138   }" + (long ? ", version: #{version}, variant: #{variant}, guid: #{to_guid}>" :  ">")
139 end
seconds() click to toggle source
    # File lib/simple_uuid.rb
111 def seconds
112   total_usecs / 1_000_000
113 end
to_guid() click to toggle source
    # File lib/simple_uuid.rb
104 def to_guid
105   elements = @bytes.unpack("NnnCCa6")
106   node = elements[-1].unpack('C*')
107   elements[-1] = '%02x%02x%02x%02x%02x%02x' % node
108   "%08x-%04x-%04x-%02x%02x-%s" % elements
109 end
to_i() click to toggle source
   # File lib/simple_uuid.rb
86 def to_i
87   ints = @bytes.unpack("NNNN")
88   (ints[0] << 96) +
89   (ints[1] << 64) +
90   (ints[2] << 32) +
91   ints[3]
92 end
to_s() click to toggle source
    # File lib/simple_uuid.rb
141 def to_s
142   @bytes
143 end
Also aliased as: bytes
to_time() click to toggle source

Return a time object

    # File lib/simple_uuid.rb
161 def to_time
162   Time.at(total_usecs / 1_000_000, total_usecs % 1_000_000)
163 end
usecs() click to toggle source
    # File lib/simple_uuid.rb
115 def usecs
116   total_usecs % 1_000_000
117 end
variant() click to toggle source
    # File lib/simple_uuid.rb
100 def variant
101   @bytes.unpack('QnnN')[1] >> 13
102 end
version() click to toggle source
   # File lib/simple_uuid.rb
94 def version
95   time_high = @bytes.unpack("NnnQ")[2]
96   version = (time_high & 0xF000).to_s(16)[0].chr.to_i
97   version > 0 and version < 6 ? version : -1
98 end

Private Instance Methods

total_usecs() click to toggle source
    # File lib/simple_uuid.rb
173 def total_usecs
174   @total_usecs ||= self.class.total_usecs(@bytes)
175 end