class JSON::Util::UUID

Constants

NameSpace_DNS

Pre-defined UUID Namespaces described in RFC4122 Appendix C.

NameSpace_OID
NameSpace_URL
NameSpace_X500
Nil

The Nil UUID in RFC4122 Section 4.1.7

STATE_FILE

Public Class Methods

create(clock=nil, time=nil, mac_addr=nil) click to toggle source

create the “version 1” UUID with current system clock, current UTC timestamp, and the IEEE 802 address (so-called MAC address).

Speed notice: it's slow. It writes some data into hard drive on every invokation. If you want to speed this up, try remounting tmpdir with a memory based filesystem (such as tmpfs). STILL slow? then no way but rewrite it with c :)

# File lib/json-schema/util/uuid.rb, line 139
def create clock=nil, time=nil, mac_addr=nil
        c = t = m = nil
        Dir.chdir Dir.tmpdir do
                unless FileTest.exist? STATE_FILE then
                        # Generate a pseudo MAC address because we have no pure-ruby way
                        # to know  the MAC  address of the  NIC this system  uses.  Note
                        # that cheating  with pseudo arresses here  is completely legal:
                        # see Section 4.5 of RFC4122 for details.
                        sha1 = Digest::SHA1.new
                        256.times do
                                r = [rand(0x100000000)].pack "N"
                                sha1.update r
                        end
                        str = sha1.digest
                        r = rand 14 # 20-6
                        node = str[r, 6] || str
                        if RUBY_VERSION >= "1.9.0"
                                nnode = node.bytes.to_a
                                nnode[0] |= 0x01
                                node = ''
                                nnode.each { |s| node << s.chr }
                        else
                                node[0] |= 0x01 # multicast bit
                        end
                        k = rand 0x40000
                        open STATE_FILE, 'w' do |fp|
                                fp.flock IO::LOCK_EX
                                write_state fp, k, node
                                fp.chmod 0o777 # must be world writable
                        end
                end
                open STATE_FILE, 'r+' do |fp|
                        fp.flock IO::LOCK_EX
                        c, m = read_state fp
                        c = clock % 0x4000 if clock
                        m = mac_addr if mac_addr
                        t = time
                        if t.nil? then
                                # UUID epoch is 1582/Oct/15
                                tt = Time.now
                                t = tt.to_i*10000000 + tt.tv_usec*10 + 0x01B21DD213814000
                        end
                        c = c.succ # important; increment here
                        write_state fp, c, m
                end
        end

        tl = t & 0xFFFF_FFFF
        tm = t >> 32
        tm = tm & 0xFFFF
        th = t >> 48
        th = th & 0x0FFF
        th = th | 0x1000
        cl = c & 0xFF
        ch = c & 0x3F00
        ch = ch >> 8
        ch = ch | 0x80
        pack tl, tm, th, cl, ch, m
end
Also aliased as: create_v1
create_md5(str, namespace) click to toggle source

UUID generation using MD5 (for backward compat.)

# File lib/json-schema/util/uuid.rb, line 89
def create_md5 str, namespace
        md5 = Digest::MD5.new
        md5.update namespace.raw_bytes
        md5.update str
        sum = md5.digest
        raw = mask 3, sum[0..16]
        ret = new raw
        ret.freeze
        ret
end
Also aliased as: create_v3
create_random() click to toggle source

UUID generation using random-number generator. From it's random nature, there's no warranty that the created ID is really universaly unique.

# File lib/json-schema/util/uuid.rb, line 104
def create_random
        rnd = [
                rand(0x100000000),
                rand(0x100000000),
                rand(0x100000000),
                rand(0x100000000),
        ].pack "N4"
        raw = mask 4, rnd
        ret = new raw
        ret.freeze
        ret
end
Also aliased as: create_v4
create_sha1(str, namespace) click to toggle source

UUID generation using SHA1. Recommended over create_md5. Namespace object is another UUID, some of them are pre-defined below.

# File lib/json-schema/util/uuid.rb, line 76
def create_sha1 str, namespace
        sha1 = Digest::SHA1.new
        sha1.update namespace.raw_bytes
        sha1.update str
        sum = sha1.digest
        raw = mask 5, sum[0..15]
        ret = new raw
        ret.freeze
        ret
end
Also aliased as: create_v5
create_v1(clock=nil, time=nil, mac_addr=nil)
Alias for: create
create_v3(str, namespace)
Alias for: create_md5
create_v4()
Alias for: create_random
create_v5(str, namespace)
Alias for: create_sha1
pack(tl, tm, th, ch, cl, n) click to toggle source

The 'primitive constructor' of this class Note ::pack == uuid

# File lib/json-schema/util/uuid.rb, line 213
def pack tl, tm, th, ch, cl, n
        raw = [tl, tm, th, ch, cl, n].pack "NnnCCa6"
        ret = new raw
        ret.freeze
        ret
end
parse(obj) click to toggle source

A simple GUID parser: just ignores unknown characters and convert hexadecimal dump into 16-octet object.

# File lib/json-schema/util/uuid.rb, line 202
def parse obj
        str = obj.to_s.sub /\Aurn:uuid:/, ''
        str.gsub! /[^0-9A-Fa-f]/, ''
        raw = str[0..31].lines.to_a.pack 'H*'
        ret = new raw
        ret.freeze
        ret
end

Private Class Methods

mask(v, str) click to toggle source
# File lib/json-schema/util/uuid.rb, line 65
def mask v, str
        if RUBY_VERSION >= "1.9.0"
                return mask19 v, str
        else
                return mask18 v, str
        end
end
mask18(v, str) click to toggle source
# File lib/json-schema/util/uuid.rb, line 54
            def mask18 v, str # :nodoc
                    version = [0, 16, 32, 48, 64, 80][v]
                    str[6] &= 0b00001111
                    str[6] |= version
#                   str[7] &= 0b00001111
#                   str[7] |= 0b01010000
                    str[8] &= 0b00111111
                    str[8] |= 0b10000000
                    str
            end
mask19(v, str) click to toggle source
# File lib/json-schema/util/uuid.rb, line 40
            def mask19 v, str # :nodoc
                    nstr = str.bytes.to_a
                    version = [0, 16, 32, 48, 64, 80][v]
                    nstr[6] &= 0b00001111
                    nstr[6] |= version
#                   nstr[7] &= 0b00001111
#                   nstr[7] |= 0b01010000
                    nstr[8] &= 0b00111111
                    nstr[8] |= 0b10000000
                    str = ''
                    nstr.each { |s| str << s.chr }
                    str
            end

Public Instance Methods

<=>(other) click to toggle source

UUIDs are comparable (don't know what benefits are there, though).

# File lib/json-schema/util/uuid.rb, line 269
def <=> other
        to_s <=> other.to_s
end
==(other) click to toggle source

Two UUIDs are said to be equal if and only if their (byte-order canonicalized) integer representations are equivallent. Refer RFC4122 for details.

# File lib/json-schema/util/uuid.rb, line 263
def == other
        to_i == other.to_i
end
guid()
Alias for: to_s
to_i()
Alias for: to_int
to_int() click to toggle source

Convert into 128-bit unsigned integer

# File lib/json-schema/util/uuid.rb, line 243
def to_int
        tmp = self.raw_bytes.unpack "C*"
        tmp.inject do |r, i|
                r * 256 | i
        end
end
Also aliased as: to_i
to_s() click to toggle source

Generate the string representation (a.k.a GUID) of this UUID

# File lib/json-schema/util/uuid.rb, line 228
def to_s
        a = unpack
        tmp = a[-1].unpack 'C*'
        a[-1] = sprintf '%02x%02x%02x%02x%02x%02x', *tmp
        "%08x-%04x-%04x-%02x%02x-%s" % a
end
Also aliased as: guid
to_uri() click to toggle source

Convert into a RFC4122-comforming URN representation

# File lib/json-schema/util/uuid.rb, line 237
def to_uri
        "urn:uuid:" + self.to_s
end
Also aliased as: urn
unpack() click to toggle source

The 'primitive deconstructor', or the dual to pack. Note ::pack == uuid

# File lib/json-schema/util/uuid.rb, line 223
def unpack
        raw_bytes.unpack "NnnCCa6"
end
urn()
Alias for: to_uri
version() click to toggle source

Gets the version of this UUID returns nil if bad version

# File lib/json-schema/util/uuid.rb, line 253
def version
        a = unpack
        v = (a[2] & 0xF000).to_s(16)[0].chr.to_i
        return v if (1..5).include? v
        return nil
end