Cast in C #

I have an application that has a guid variable that must be unique (of course). I know that statistically any guide should simply be considered unique, but due to dev / test environment reasons, the same value can be seen several times. Therefore, when this happens, I want to "increase" the value of Guid, and not just create a completely new one. There seems to be no easy way to do this. I found a hack that I will post as a possible answer, but want a cleaner solution.

+6
source share
4 answers

You can get the guid byte components, so you can just work on this:

static class GuidExtensions { private static readonly int[] _guidByteOrder = new[] { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 }; public static Guid Increment(this Guid guid) { var bytes = guid.ToByteArray(); bool carry = true; for (int i = 0; i < _guidByteOrder.Length && carry; i++) { int index = _guidByteOrder[i]; byte oldValue = bytes[index]++; carry = oldValue > bytes[index]; } return new Guid(bytes); } } 

EDIT: now with correct byte order

+7
source

Thanks to Thomas Levesque's byte order , here's a great LINQ implementation:

 static int[] byteOrder = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 }; static Guid NextGuid(Guid guid) { var bytes = guid.ToByteArray(); var canIncrement = byteOrder.Any(i => ++bytes[i] != 0); return new Guid(canIncrement ? bytes : new byte[16]); } 

Note that it wraps up to Guid.Empty if you manage to increase it before that.

It would be more efficient if you continued to increase one copy of bytes instead of calling ToByteArray for each GUID in turn.

+7
source

Proven solution for ordered rows:

  private static Guid Increment(Guid guid) { byte[] bytes = guid.ToByteArray(); byte[] order = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 }; for (int i = 0; i < 16; i++) { if (bytes[order[i]] == byte.MaxValue) { bytes[order[i]] = 0; } else { bytes[order[i]]++; return new Guid(bytes); } } throw new OverflowException("Congratulations you are one in a billion billion billion billion etc..."); } 

Verification:

  private static Guid IncrementProof(Guid guid, int start, int end) { byte[] bytes = guid.ToByteArray(); byte[] order = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 }; for (int i = start; i < end; i++) { if (bytes[order[i]] == byte.MaxValue) { bytes[order[i]] = 0; } else { bytes[order[i]]++; return new Guid(bytes); } } throw new OverflowException("Congratulations you are one in a billion billion billion billion etc..."); } static void Main(string[] args) { Guid temp = new Guid(); for (int j = 0; j < 16; j++) { for (int i = 0; i < 255; i++) { Console.WriteLine(temp.ToString()); temp = IncrementProof(temp, j, j + 1); } } } 
+1
source

Possible Solution. I think this works (not tested), but a better solution is needed.

 public static Guid Increment(this Guid value) { var bytes = value.ToByteArray(); // Note that the order of bytes in the returned byte array is different from the string representation of a Guid value. // Guid: 00112233-4455-6677-8899-aabbccddeeff // byte array: 33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF // So the byte order of the following indexes indicates the true low-to-high sequence if (++bytes[15] == 0) if (++bytes[14] == 0) if (++bytes[13] == 0) if (++bytes[12] == 0) if (++bytes[11] == 0) if (++bytes[10] == 0) // normal order if (++bytes[9] == 0) if (++bytes[8] == 0) // normal order if (++bytes[6] == 0) if (++bytes[7] == 0) // reverse order if (++bytes[5] == 0) if (++bytes[4] == 0) // reverse order if (++bytes[3] == 0) if (++bytes[2] == 0) if (++bytes[1] == 0) { ++bytes[0]; } // reverse order return new Guid(bytes); } 

Edit: here is the code I used; the props of the answers above are for general techniques, although without an “unverified” sentence they both threw exceptions in some cases. But I also tried to make it as readable as possible.

 private static int[] _guidByteOrder = { 15, 14, 13, 12, 11, 10, 9, 8, 6, 7, 4, 5, 0, 1, 2, 3 }; public static Guid NextGuid(this Guid guid) { var bytes = guid.ToByteArray(); for (int i = 0; i < 16; i++) { var iByte = _guidByteOrder[i]; unchecked { bytes[iByte] += 1; } if (bytes[iByte] != 0) return new Guid(bytes); } return Guid.Empty; } 
0
source

Source: https://habr.com/ru/post/987770/


All Articles