Hah, this is a slightly awkward artefact of three things:
-
.NET ‘serializes’ UUIDs (it calls them GUIDs) in a way which can only be described as crazy. I have no doubt that it was done for ‘backwards compatibility’ but that’s no excuse really.
-
This wasn’t discovered until in .NET version of protocol buffers until such time as it was too late to change.
-
The initial ES client was .NET so it wasn’t noticed until it was too late.
I’m not sure how you’d do it in Haskell, but in Java this will create a UUID from a byte array containing the .NET serialisation:
private static final int[] mostOrder = new int[]{3,2,1,0,5,4,7,6};
private static UUID uuidFromCrazyEndian(byte[] dotNetEncodedGuid) {
long most = 0;
long least = 0;
for (int i : mostOrder) {
most = (most << 8) | (dotNetEncodedGuid[i] & 0xFF);
}
for (int i = 8; i < 16; i++) {
least = (least << 8) | (dotNetEncodedGuid[i] & 0xFF);
}
return new UUID(most, least);
}
Here is the same thing in Go:
var order = […]int{3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15}
func crazyEndianToUUID(netEncoded []byte) uuid.UUID {
uuidBytes := make([]byte, 16)
for i := 0; i < len(order); i++ {
uuidBytes[i] = netEncoded[order[i]]
}
return uuidBytes
}
However, you don’t actually need to make these UUIDs except for debugging/reporting purposes - you’ll get the same bytes back but the display won’t correlate.
Hope this helps, great work with the client!
Cheers,
James