-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
UUIDv5.ps1
89 lines (72 loc) · 3.29 KB
/
UUIDv5.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
$ErrorActionPreference="Stop"
$Source = @"
using System;
using System.Security.Cryptography;
using System.Text;
public static class UUIDv5
{
public static Guid Create(Guid namespaceId, string name)
{
if (name == null)
throw new ArgumentNullException("name");
// convert the name to a sequence of octets (as defined by the standard or conventions of its namespace) (step 3)
// ASSUME: UTF-8 encoding is always appropriate
byte[] nameBytes = Encoding.UTF8.GetBytes(name);
// convert the namespace UUID to network order (step 3)
byte[] namespaceBytes = namespaceId.ToByteArray();
SwapByteOrder(namespaceBytes);
// comput the hash of the name space ID concatenated with the name (step 4)
byte[] hash;
using (HashAlgorithm algorithm = SHA1.Create())
{
algorithm.TransformBlock(namespaceBytes, 0, namespaceBytes.Length, null, 0);
algorithm.TransformFinalBlock(nameBytes, 0, nameBytes.Length);
hash = algorithm.Hash;
}
// most bytes from the hash are copied straight to the bytes of the new GUID (steps 5-7, 9, 11-12)
byte[] newGuid = new byte[16];
Array.Copy(hash, 0, newGuid, 0, 16);
// 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] = (byte)((newGuid[6] & 0x0F) | (5 << 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] = (byte)((newGuid[8] & 0x3F) | 0x80);
// convert the resulting UUID to local byte order (step 13)
SwapByteOrder(newGuid);
return new Guid(newGuid);
}
/// <summary>
/// The namespace for fully-qualified domain names (from RFC 4122, Appendix C).
/// </summary>
public static readonly Guid DnsNamespace = new Guid("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
/// <summary>
/// The namespace for URLs (from RFC 4122, Appendix C).
/// </summary>
public static readonly Guid UrlNamespace = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
/// <summary>
/// The namespace for ISO OIDs (from RFC 4122, Appendix C).
/// </summary>
public static readonly Guid IsoOidNamespace = new Guid("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
// Converts a GUID (expressed as a byte array) to/from network order (MSB-first).
internal static void SwapByteOrder(byte[] guid)
{
SwapBytes(guid, 0, 3);
SwapBytes(guid, 1, 2);
SwapBytes(guid, 4, 5);
SwapBytes(guid, 6, 7);
}
private static void SwapBytes(byte[] guid, int left, int right)
{
byte temp = guid[left];
guid[left] = guid[right];
guid[right] = temp;
}
}
"@
Add-Type -TypeDefinition $Source -Language CSharp
function Get-UUIDv5 {
param(
[guid] $namespace,
[string] $name
)
return [UUIDv5]::Create([guid]$manifest.id, [string]$manifest.name).ToString()
}