Skip to content

Instantly share code, notes, and snippets.

@Ephasme
Forked from ChrisMcKee/PredicatableGuid.cs
Last active December 5, 2017 12:38
Show Gist options
  • Save Ephasme/8fd433358f9a426fd8325cdce100e5d9 to your computer and use it in GitHub Desktop.
Save Ephasme/8fd433358f9a426fd8325cdce100e5d9 to your computer and use it in GitHub Desktop.
Namespaced Deterministic Guid - RFC 4122 dotnetcore
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
namespace Utility
{
public static class GuidUtility
{
private static Guid Url { get; } = new Guid("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
public static Guid CreateForUrl(string name) => Create(Url, name);
private static Guid Create(Guid namespaceId, string name, int version = 5)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (version != 3 && version != 5 && version != 6)
throw new ArgumentOutOfRangeException(nameof(version), "version must be either 3 (md5) or 5 (sha1), or 6 (sha256).");
var nameBytes = Encoding.UTF8.GetBytes(name);
var namespaceBytes = namespaceId.ToByteArray();
SwapByteOrder(namespaceBytes);
byte[] hash;
using (var incrementalHash = version == 3 ? IncrementalHash.CreateHash(HashAlgorithmName.MD5) : version == 5 ? IncrementalHash.CreateHash(HashAlgorithmName.SHA1) : IncrementalHash.CreateHash(HashAlgorithmName.SHA256))
{
incrementalHash.AppendData(namespaceBytes);
incrementalHash.AppendData(nameBytes);
hash = incrementalHash.GetHashAndReset();
}
var newGuid = new byte[16];
Array.Copy(hash, 0, newGuid, 0, 16);
newGuid[6] = (byte)((newGuid[6] & 0x0F) | (version << 4));
newGuid[8] = (byte)((newGuid[8] & 0x3F) | 0x80);
SwapByteOrder(newGuid);
return new Guid(newGuid);
}
private static void SwapByteOrder(IList<byte> guid)
{
SwapBytes(guid, 0, 3);
SwapBytes(guid, 1, 2);
SwapBytes(guid, 4, 5);
SwapBytes(guid, 6, 7);
}
private static void SwapBytes(IList<byte> guid, int left, int right)
{
var temp = guid[left];
guid[left] = guid[right];
guid[right] = temp;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment