Created
January 17, 2022 11:39
-
-
Save JPRuskin/8992e5665a3a73316bba3089de074078 to your computer and use it in GitHub Desktop.
Converts a string to an RFC 4122 compatible UUID.
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
function SwapBytes { | |
<# | |
.SYNOPSIS | |
Simply switches two bytes in an array of bytes | |
#> | |
param( | |
[Parameter(Mandatory)] | |
[byte[]]$Guid, | |
[Parameter(Mandatory)] | |
[int]$Left, | |
[Parameter(Mandatory)] | |
[int]$Right | |
) | |
$Guid[$Left], $Guid[$Right] = $Guid[$Right], $Guid[$Left] | |
} | |
function SwapByteOrder { | |
<# | |
.SYNOPSIS | |
Convert between Local and Network order | |
#> | |
param( | |
[byte[]]$Guid | |
) | |
SwapBytes $Guid 0 3 | |
SwapBytes $Guid 1 2 | |
SwapBytes $Guid 4 5 | |
SwapBytes $Guid 6 7 | |
} | |
function ConvertTo-Guid { | |
<# | |
.Synopsis | |
Converts a string (or bytes) into a deterministic GUID, based on a specific namespace | |
.Link | |
https://www.ietf.org/rfc/rfc4122.txt | |
RFC | |
.Link | |
https://github.com/Faithlife/FaithlifeUtility/blob/master/src/Faithlife.Utility/GuidUtility.cs | |
Original by Bradley Grainger | |
.Example | |
ConvertTo-Guid 'env.CCR_Api_Key' | |
#> | |
[CmdletBinding(DefaultParameterSetName="FromString")] | |
param( | |
[Parameter(Mandatory, Position=0, ParameterSetName = "FromString")] | |
[string]$String, | |
[Parameter(Mandatory, ParameterSetName = "FromBytes")] | |
[byte[]]$Bytes = $([System.Text.Encoding]::UTF8.GetBytes($String)), | |
[ValidateSet( | |
"6ba7b810-9dad-11d1-80b4-00c04fd430c8", # DnsNamespace | |
"6ba7b811-9dad-11d1-80b4-00c04fd430c8", # UrlNamespace | |
"6ba7b812-9dad-11d1-80b4-00c04fd430c8", # IsoOidNamespace | |
"361E6D51-FAEC-444A-9079-341386DA8E2E" # Ansible, should be v5 | |
)] | |
[guid]$NamespaceId = "361E6D51-FAEC-444A-9079-341386DA8E2E", | |
[ValidateSet(3,5)] | |
$Version = 5 | |
) | |
process { | |
# Convert the namespace UUID to network order (step 3) | |
$NamespaceBytes = $NamespaceId.ToByteArray() | |
SwapByteOrder $NamespaceBytes | |
# Compute the hash of the namespace ID concatenated with the name (step 4) | |
$Data = $NamespaceBytes + $Bytes | |
[byte[]]$Hash = switch ($Version) { | |
3 { [System.Security.Cryptography.MD5]::Create().ComputeHash($Data) } | |
5 { [System.Security.Cryptography.SHA1]::Create().ComputeHash($Data) } | |
} | |
$NewGuid = [byte[]]$Hash[0..15] | |
# Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field | |
# to the appropriate 4-bit version number from Section 4.1.3 (step 8) | |
$NewGuid[6] = $NewGuid[6] -band 0x0F -bor $Version -shl 4 | |
# Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to | |
# zero and one, respectively (step 10) | |
$NewGuid[8] = $NewGuid[8] -band 0x3F -bor 0x80 | |
SwapByteOrder($NewGuid) | |
[Guid]$NewGuid | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment