Created
August 21, 2019 13:13
-
-
Save KristofferC/40e31d71a93c73988ba47b793f14264d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ``` | |
| - # This file is a part of Julia. License is MIT: https://julialang.org/license | |
| - | |
| - module UUIDs | |
| - | |
| - using Random | |
| - | |
| - import SHA | |
| - | |
| - export UUID, uuid1, uuid4, uuid5, uuid_version | |
| - | |
| - import Base: UUID | |
| - | |
| - """ | |
| - uuid_version(u::UUID) -> Int | |
| - | |
| - Inspects the given UUID and returns its version | |
| - (see [RFC 4122](https://www.ietf.org/rfc/rfc4122)). | |
| - | |
| - # Examples | |
| - ```jldoctest | |
| - julia> uuid_version(uuid4()) | |
| - 4 | |
| - ``` | |
| - """ | |
| 6 uuid_version(u::UUID) = Int((u.value >> 76) & 0xf) | |
| - | |
| - # Some UUID namespaces provided in the appendix of RFC 4122 | |
| - # https://tools.ietf.org/html/rfc4122.html#appendix-C | |
| - const namespace_dns = UUID(0x6ba7b8109dad11d180b400c04fd430c8) # 6ba7b810-9dad-11d1-80b4-00c04fd430c8 | |
| - const namespace_url = UUID(0x6ba7b8119dad11d180b400c04fd430c8) # 6ba7b811-9dad-11d1-80b4-00c04fd430c8 | |
| - const namespace_oid = UUID(0x6ba7b8129dad11d180b400c04fd430c8) # 6ba7b812-9dad-11d1-80b4-00c04fd430c8 | |
| - const namespace_x500 = UUID(0x6ba7b8149dad11d180b400c04fd430c8) # 6ba7b814-9dad-11d1-80b4-00c04fd430c8 | |
| - | |
| - """ | |
| - uuid1([rng::AbstractRNG=GLOBAL_RNG]) -> UUID | |
| - | |
| - Generates a version 1 (time-based) universally unique identifier (UUID), as specified | |
| - by RFC 4122. Note that the Node ID is randomly generated (does not identify the host) | |
| - according to section 4.5 of the RFC. | |
| - | |
| - # Examples | |
| - ```jldoctest; filter = r"[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}" | |
| - julia> rng = MersenneTwister(1234); | |
| - | |
| - julia> uuid1(rng) | |
| - UUID("cfc395e8-590f-11e8-1f13-43a2532b2fa8") | |
| - ``` | |
| - """ | |
| - function uuid1(rng::AbstractRNG=Random.default_rng()) | |
| 4 u = rand(rng, UInt128) | |
| - | |
| - # mask off clock sequence and node | |
| 1 u &= 0x00000000000000003fffffffffffffff | |
| - | |
| - # set the unicast/multicast bit and version | |
| 1 u |= 0x00000000000010000000010000000000 | |
| - | |
| - # 0x01b21dd213814000 is the number of 100 nanosecond intervals | |
| - # between the UUID epoch and Unix epoch | |
| 1 timestamp = round(UInt64, time() * 1e7) + 0x01b21dd213814000 | |
| 1 ts_low = timestamp & typemax(UInt32) | |
| 1 ts_mid = (timestamp >> 32) & typemax(UInt16) | |
| 1 ts_hi = (timestamp >> 48) & 0x0fff | |
| - | |
| 1 u |= UInt128(ts_low) << 96 | |
| 1 u |= UInt128(ts_mid) << 80 | |
| 1 u |= UInt128(ts_hi) << 64 | |
| - | |
| 1 UUID(u) | |
| - end | |
| - | |
| - """ | |
| - uuid4([rng::AbstractRNG=GLOBAL_RNG]) -> UUID | |
| - | |
| - Generates a version 4 (random or pseudo-random) universally unique identifier (UUID), | |
| - as specified by RFC 4122. | |
| - | |
| - # Examples | |
| - ```jldoctest | |
| - julia> rng = MersenneTwister(1234); | |
| - | |
| - julia> uuid4(rng) | |
| - UUID("196f2941-2d58-45ba-9f13-43a2532b2fa8") | |
| - ``` | |
| - """ | |
| - function uuid4(rng::AbstractRNG=Random.default_rng()) | |
| 7 u = rand(rng, UInt128) | |
| 3 u &= 0xffffffffffff0fff3fffffffffffffff | |
| 3 u |= 0x00000000000040008000000000000000 | |
| 3 UUID(u) | |
| - end | |
| - | |
| - """ | |
| - uuid5(ns::UUID, name::String) -> UUID | |
| - | |
| - Generates a version 5 (namespace and domain-based) universally unique identifier (UUID), | |
| - as specified by RFC 4122. | |
| - | |
| - !!! compat "Julia 1.1" | |
| - This function requires at least Julia 1.1. | |
| - | |
| - # Examples | |
| - ```jldoctest | |
| - julia> rng = MersenneTwister(1234); | |
| - | |
| - julia> u4 = uuid4(rng) | |
| - UUID("196f2941-2d58-45ba-9f13-43a2532b2fa8") | |
| - | |
| - julia> u5 = uuid5(u4, "julia") | |
| - UUID("b37756f8-b0c0-54cd-a466-19b3d25683bc") | |
| - ``` | |
| - """ | |
| - function uuid5(ns::UUID, name::String) | |
| 20 nsbytes = zeros(UInt8, 16) | |
| 10 nsv = ns.value | |
| 10 for idx in Base.OneTo(16) | |
| 160 nsbytes[idx] = nsv >> 120 | |
| 310 nsv = nsv << 8 | |
| - end | |
| 10 hash_result = SHA.sha1(append!(nsbytes, convert(Vector{UInt8}, codeunits(unescape_string(name))))) | |
| - # set version number to 5 | |
| 10 hash_result[7] = (hash_result[7] & 0x0F) | (0x50) | |
| 10 hash_result[9] = (hash_result[9] & 0x3F) | (0x80) | |
| - v = zero(UInt128) | |
| - #use only the first 16 bytes of the SHA1 hash | |
| 10 for idx in Base.OneTo(16) | |
| 310 v = (v << 0x08) | hash_result[idx] | |
| - end | |
| 10 return UUID(v) | |
| - end | |
| - | |
| - end | |
| - | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment