While working on a project I needed to generate fake data for my tests. After a little searching I came across Faker.NET. Although this post isn’t about Faker.NET it is the catalyst.
The fake data I was generating has GUID identifiers, and although it is very simple to generate GUIDs I wanted to generate the same GUID every time. Using the GUID constructors is cumbersome so I decided I would much prefer to pass in an simple value like an integer and have a GUID generated from that. Turns out that’s a trivial task but the resulting extension methods have come in rather handy, and I wanted to share them.
One side note about the string overload method. This method is simply using the hash code for the string to generated the GUID. This allows for long strings but the rules for strings and hash codes also apply. Meaning that two identical strings will give you the same GUID, but it is possible for two different strings to generate the same GUID. It is not guaranteed to be unique.
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 |
public static class GuidExtensions { public static Guid ToGuid(this short value) { return ConvertToGuid((ulong)value); } public static Guid ToGuid(this ushort value) { return ConvertToGuid(value); } public static Guid ToGuid(this int value) { return ConvertToGuid((ulong) value); } public static Guid ToGuid(this uint value) { return ConvertToGuid(value); } public static Guid ToGuid(this long value) { return ConvertToGuid((ulong)value); } public static Guid ToGuid(this ulong value) { return ConvertToGuid(value); } public static Guid ToGuid(this string value) { return string.IsNullOrEmpty(value) ? Guid.Empty : ToGuid((ulong) value.GetHashCode()); } public static Guid ToGuid(this DateTime value) { return ConvertToGuid((ulong)value.Ticks); } internal static Guid ConvertToGuid(ulong value) { var valueBytes = BitConverter.GetBytes(value).Reverse().ToArray(); var emptyBytes = Guid.Empty.ToByteArray().Take(16 - valueBytes.Length); var guidBytes = emptyBytes.Concat(valueBytes).ToArray(); return new Guid(guidBytes); } } |
Generating sequential GUIDs is now rather straight forward.
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 |
for (int i = 0; i < 33; i++) { Debug.WriteLine("Value {0} = {1}", i, i.ToGuid()); } Debug Trace: Value 0 = 00000000-0000-0000-0000-000000000000 Value 1 = 00000000-0000-0000-0000-000000000001 Value 2 = 00000000-0000-0000-0000-000000000002 Value 3 = 00000000-0000-0000-0000-000000000003 Value 4 = 00000000-0000-0000-0000-000000000004 Value 5 = 00000000-0000-0000-0000-000000000005 Value 6 = 00000000-0000-0000-0000-000000000006 Value 7 = 00000000-0000-0000-0000-000000000007 Value 8 = 00000000-0000-0000-0000-000000000008 Value 9 = 00000000-0000-0000-0000-000000000009 Value 10 = 00000000-0000-0000-0000-00000000000a Value 11 = 00000000-0000-0000-0000-00000000000b Value 12 = 00000000-0000-0000-0000-00000000000c Value 13 = 00000000-0000-0000-0000-00000000000d Value 14 = 00000000-0000-0000-0000-00000000000e Value 15 = 00000000-0000-0000-0000-00000000000f Value 16 = 00000000-0000-0000-0000-000000000010 Value 17 = 00000000-0000-0000-0000-000000000011 Value 18 = 00000000-0000-0000-0000-000000000012 Value 19 = 00000000-0000-0000-0000-000000000013 Value 20 = 00000000-0000-0000-0000-000000000014 Value 21 = 00000000-0000-0000-0000-000000000015 Value 22 = 00000000-0000-0000-0000-000000000016 Value 23 = 00000000-0000-0000-0000-000000000017 Value 24 = 00000000-0000-0000-0000-000000000018 Value 25 = 00000000-0000-0000-0000-000000000019 Value 26 = 00000000-0000-0000-0000-00000000001a Value 27 = 00000000-0000-0000-0000-00000000001b Value 28 = 00000000-0000-0000-0000-00000000001c Value 29 = 00000000-0000-0000-0000-00000000001d Value 30 = 00000000-0000-0000-0000-00000000001e Value 31 = 00000000-0000-0000-0000-00000000001f Value 32 = 00000000-0000-0000-0000-000000000020 |
Some additional tests.
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 |
Debug.WriteLine("Short Max Value {0} = {1}", short.MaxValue, short.MaxValue.ToGuid()); Debug.WriteLine("Unsigned Short Max Value {0} = {1}", ushort.MaxValue, ushort.MaxValue.ToGuid()); Debug.WriteLine("Int Max Value {0} = {1}", int.MaxValue, int.MaxValue.ToGuid()); Debug.WriteLine("Unsigned Int Max Value {0} = {1}", uint.MaxValue, uint.MaxValue.ToGuid()); Debug.WriteLine("Long Max Value {0} = {1}", long.MaxValue, long.MaxValue.ToGuid()); Debug.WriteLine("Unsigned Long Max Value {0} = {1}", ulong.MaxValue, ulong.MaxValue.ToGuid()); Debug.WriteLine("UTC Date Time Now {0} = {1}", DateTime.UtcNow, DateTime.UtcNow.ToGuid()); Debug.WriteLine("Max Date Time {0} = {1}", DateTime.MaxValue, DateTime.MaxValue.ToGuid()); var value = "Hello World"; Debug.WriteLine("String \"{0}\" = {1}", value, value.ToGuid()); Debug Trace: Short Max Value 32767 = 00000000-0000-0000-0000-000000007fff Unsigned Short Max Value 65535 = 00000000-0000-0000-0000-00000000ffff Int Max Value 2147483647 = 00000000-0000-0000-0000-00007fffffff Unsigned Int Max Value 4294967295 = 00000000-0000-0000-0000-0000ffffffff Long Max Value 9223372036854775807 = 00000000-0000-0000-7fff-ffffffffffff Unsigned Long Max Value 18446744073709551615 = 00000000-0000-0000-ffff-ffffffffffff UTC Date Time Now 02/07/2015 16:28:26 = 00000000-0000-0000-08d2-110a3bda2d4d Max Date Time 12/31/9999 23:59:59 = 00000000-0000-0000-2bca-2875f4373fff String "Hello World" = 00000000-0000-0000-0000-0000541f3ae8 |
As you can see there are a lot of leading zeros which opens up the idea of additional methods that could be used to generate upper values. I think I’ll leave that for another post.
Leave a Reply
You must be logged in to post a comment.