56

When you call ToByteArray() on a GUID in .NET, the ordering of the bytes in the resulting array is not what you'd expect as compared to the string representation of the GUID. For example, for the following GUID represented as a string:

11223344-5566-7788-9900-aabbccddeeff

The result of ToByteArray() is this:

44, 33, 22, 11, 66, 55, 88, 77, 99, 00, AA, BB, CC, DD, EE, FF

Note that the order of the first four bytes is reversed. Also bytes 4 and 5 are swapped and bytes 6 and 7 are swapped. But the final 8 bytes are in the same order they're represented as in the string.

I understand that this is occurring. What I would like to know is why .NET handles it this way.

For reference, you can see some discussion and confusion about this (incorrect attributed to Oracle databases) here and here.

Community
  • 1
  • 1
Cory McCarty
  • 1,375
  • 4
  • 15
  • 23
  • 1
    Also see http://stackoverflow.com/questions/8064648/net-native-guid-conversion and [this Eric Lippert blogpost from **2004** !](http://blogs.msdn.com/b/ericlippert/archive/2004/05/25/141525.aspx) – AakashM Feb 08 '12 at 14:50
  • 2
    a) it really does not matter. b) it's a big little endian issue. – H H Feb 08 '12 at 14:51
  • 39
    a) It really does matter when it's bitten you. Also, having a better understanding of not only how things work, but also why they work that way, makes you better able to avoid being bitten by counterintuitive behaviors like this. b) It was fairly clear from the start that it's an endian-ness issue. But it's particularly perplexing because the final 8 bytes are left in their original order. Also, if you're going to represent a GUID as a string of hex, wouldn't it make more sense to represent it in the actual byte order? – Cory McCarty Feb 08 '12 at 14:54
  • @CoryMcCarty: it shouldn't be perplexing that the final 8 bytes are left in order. A byte stream is not affected by endianness because individual bytes have no endianness. – user7116 Feb 08 '12 at 15:01
  • Which is why I'm asking about it. As a professional, I'd like to know what I was doing wrong and why. The fact that I was doing something wrong was pretty obvious. – Cory McCarty Feb 08 '12 at 15:02
  • @sixlettervariables: Yeah, your answer was exactly what I was looking for. I'd missed the constructor explanation because I was looking at the documentation for ToByteArray(). Also, thanks to AakashM for providing some helpful background. – Cory McCarty Feb 08 '12 at 15:04
  • 7
    @aakashM: Wow, I had forgotten entirely about that. I read this question and thought "hmm, this might make a good blog article". This is not the first time I've thought that about something I've already written, either. – Eric Lippert Feb 08 '12 at 16:13
  • 3
    @Eric happens to me all the time: Run into a problem, Google the problem, find a result on StackOverflow that helps me, realize that I'm the one who either asked or even answered the question, 2+ years ago. – Michael Stum Feb 08 '12 at 18:03

1 Answers1

34

If you read the Examples section from the GUID constructor, you'll find your answer:

Guid(1,2,3,new byte[]{0,1,2,3,4,5,6,7}) creates a Guid that corresponds to "00000001-0002-0003-0001-020304050607".

a is a 32-bit integer, b is a 16-bit integer, c is a 16-bit integer, and d is simply 8 bytes.

Because a, b, and c are integer types rather than raw bytes, they are subject to endian ordering when choosing how to display them. The RFC for GUID's (RFC4122) states that they should be presented in big endian format.

user7116
  • 63,008
  • 17
  • 141
  • 172
  • 5
    The RFC 4122 format specification applies to how a GUID is to be encoded "on the wire", and only in the absence of contextual requirements to the contrary. That said, the output of `ToByteArray` is awkward because the little-endian fields break field-oblivious binary sortability. – Jeffrey Hantin Jan 27 '15 at 02:15