Last active
August 16, 2021 02:15
-
-
Save AlexeyRaga/eba296868379a9225f4b20b30e65e822 to your computer and use it in GitHub Desktop.
This file contains 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
open System | |
open System.Security.Cryptography | |
open System.Text | |
[<RequireQualifiedAccess>] | |
module Guid = | |
let private hashProvider = SHA1.Create() | |
let private sha1 (bytes: byte array) = hashProvider.ComputeHash(bytes) | |
let inline private swapOrder arr = | |
let inline swapBytes a b (arr: byte array) = | |
let t = arr.[a] | |
arr.[a] <- arr.[b] | |
arr.[b] <- t | |
arr | |
// Microsoft uses (Int32, Int16, Int16, Byte[8]) structure to represent Guid. | |
// Which makes representation of first 8 bytes in a "wrong" order | |
// (because Int32 and Int16 are little-endian in dotnet) | |
arr | |
|> swapBytes 0 3 | |
|> swapBytes 1 2 | |
|> swapBytes 4 5 | |
|> swapBytes 6 7 | |
/// This function implements RFC 4122 for UUID v5. | |
/// | |
/// GUID v5 is used for deterministically creating "namespaced" unique identifiers. | |
/// Which reads as "An identifier for a given name within a given namespace". | |
let createNamespaced (namespaceId: Guid) (name: byte array) = | |
let ns = namespaceId.ToByteArray() |> swapOrder | |
let bytes = ns |> Array.append name |> sha1 |> Array.take 16 | |
// indicate v5 UUID: set bits 12-15 | |
bytes.[6] <- (bytes.[6] &&& 0x0Fuy) ||| 0x50uy | |
// ser bits 6-7 to 0 and 1 | |
bytes.[8] <- (bytes.[8] &&& 0x3Fuy) ||| 0x80uy | |
bytes |> swapOrder |> Guid | |
let createNamespacedForGuid (namespaceId: Guid) (value: Guid) = | |
value.ToByteArray() | |
|> swapOrder | |
|> createNamespaced namespaceId | |
let createNamespacedForName (namespaceId: Guid) (name: string) = | |
Encoding.UTF8.GetBytes(name) | |
|> createNamespaced namespaceId |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment