Skip to content

Instantly share code, notes, and snippets.

@KristofferC
Created August 21, 2019 13:13
Show Gist options
  • Select an option

  • Save KristofferC/40e31d71a93c73988ba47b793f14264d to your computer and use it in GitHub Desktop.

Select an option

Save KristofferC/40e31d71a93c73988ba47b793f14264d to your computer and use it in GitHub Desktop.
```
- # 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