Class: SimpleUUID::UUID
- Inherits:
-
Object
- Object
- SimpleUUID::UUID
- 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
-
.to_time(bytes) ⇒ Object
Given raw bytes, return a time object.
-
.total_usecs(bytes) ⇒ Object
Given raw bytes, return the total_usecs.
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #eql?(other) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(bytes = nil, opts = {}) ⇒ UUID
constructor
A new instance of UUID.
- #inspect(long = false) ⇒ Object
- #seconds ⇒ Object
- #to_guid ⇒ Object
- #to_i ⇒ Object
- #to_s ⇒ Object (also: #bytes)
-
#to_time ⇒ Object
Return a time object.
- #usecs ⇒ Object
- #variant ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(bytes = nil, opts = {}) ⇒ 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/simple_uuid.rb', line 23 def initialize(bytes = nil, opts = {}) case bytes when self.class # UUID @bytes = bytes.to_s when String case bytes.size when 16 # Raw byte array @bytes = bytes.respond_to?(:force_encoding) ? bytes.force_encoding("ASCII-8BIT") : 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/ byte_array = [ time & 0xFFFF_FFFF, time >> 32, ((time >> 48) & 0x0FFF) | 0x1000, ] # Top 3 bytes reserved if opts[:randomize] == false byte_array += if !opts[:salt].nil? clock_h, clock_l, node_h, node_l = opts[:salt].to_s.unpack("CCnN") clock = [ clock_h | VARIANT, clock_l ].pack("n").unpack("n").first [ clock, node_h, node_l ] else [ 0 | VARIANT, 0, 0 ] end else byte_array += [ rand(2**13) | VARIANT, rand(2**16), rand(2**32) ] end @bytes = byte_array.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
155 156 157 158 |
# File 'lib/simple_uuid.rb', line 155 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
166 167 168 169 |
# File 'lib/simple_uuid.rb', line 166 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
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/simple_uuid.rb', line 119 def <=>(other) me = to_s.unpack('Nn2C*') him = other.to_s.unpack('Nn2C*') # swap most significant time bits to front me[0], me[2], him[0], him[2] = me[2], me[0], him[2], him[0] me.zip(him) do |m, h| comp = m <=> h return comp if comp != 0 end return 0 end |
#eql?(other) ⇒ Boolean
150 151 152 |
# File 'lib/simple_uuid.rb', line 150 def eql?(other) other.respond_to?(:bytes) && bytes == other.bytes end |
#hash ⇒ Object
146 147 148 |
# File 'lib/simple_uuid.rb', line 146 def hash @bytes.hash end |
#inspect(long = false) ⇒ Object
131 132 133 134 135 136 137 138 139 |
# File 'lib/simple_uuid.rb', line 131 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 |
#seconds ⇒ Object
111 112 113 |
# File 'lib/simple_uuid.rb', line 111 def seconds total_usecs / 1_000_000 end |
#to_guid ⇒ Object
104 105 106 107 108 109 |
# File 'lib/simple_uuid.rb', line 104 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_i ⇒ Object
86 87 88 89 90 91 92 |
# File 'lib/simple_uuid.rb', line 86 def to_i ints = @bytes.unpack("NNNN") (ints[0] << 96) + (ints[1] << 64) + (ints[2] << 32) + ints[3] end |
#to_s ⇒ Object Also known as: bytes
141 142 143 |
# File 'lib/simple_uuid.rb', line 141 def to_s @bytes end |
#to_time ⇒ Object
Return a time object
161 162 163 |
# File 'lib/simple_uuid.rb', line 161 def to_time Time.at(total_usecs / 1_000_000, total_usecs % 1_000_000) end |
#usecs ⇒ Object
115 116 117 |
# File 'lib/simple_uuid.rb', line 115 def usecs total_usecs % 1_000_000 end |
#variant ⇒ Object
100 101 102 |
# File 'lib/simple_uuid.rb', line 100 def variant @bytes.unpack('QnnN')[1] >> 13 end |
#version ⇒ Object
94 95 96 97 98 |
# File 'lib/simple_uuid.rb', line 94 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 |