OK, I owe you an apology here; basically, the v1 version of protobuf-net used Guid.ToByteArray
, which - if I had to give it a name - I would have to call "crazy-endian" - and it uses what is perhaps a bad design choice of layouts. To illustrate the "crazy-endian":
var guid = new Guid("00112233445566778899AABBCCDDEEFF");
var msBlob = guid.ToByteArray();
var msHex = BitConverter.ToString(msBlob);
Obviously... msHex
is the string:
33-22-11-00-55-44-77-66-88-99-AA-BB-CC-DD-EE-FF
You should be able to see how each input / output byte maps in the above; I mean, who wouldn't choose that as the obvious choice of Guid.ToByteArray
? Just... sigh.
OK, so... that's odd... but: this unusual order wasn't noticed when v1 chose to use ToByteArray
. Although, IIRC it was noticed how odd it was when v2 needed to prove compatibility (v2 initially made the assumption that it was implemented in a "sane" way, and immediately failed all the tests).
Now, protobuf-net uses the layout defined in bcl.proto, specifically:
message Guid {
optional fixed64 lo = 1; // the first 8 bytes of the guid
optional fixed64 hi = 2; // the second 8 bytes of the guid
}
So - a sub-message containing two fields, a lo
and a hi
. The field headers for field 1 fixed64 and field 2 fixed64 are 09
and 11
respectively, so we should expect:
09-33-22-11-00-55-44-77-66-11-88-99-AA-BB-CC-DD-EE-FF
which is... yeah, that's kinda sucky. A poor design choice. If I could go back and re-make that decision, I would have made it just a bytes
of expected length 16, and I would have fixed the endianness. Well, hindsight is great. It is, however, hugely problematic to revert a poor decision that was made many years ago without impacting existing code.
So that's 18 bytes accounted for. The final 2 bytes are almost certainly a leading 0A-12
, which means "field 1, length delimited: 18 bytes".
So; you have options:
- decode as a
lo
/hi
pair, and account for the crazy-endianness (for which I have nothing to offer but apologies) - change the .NET code to advertise the value as a
byte[]
instead - there's also a case to be made for a feature request to implement
Guid
in a sane way out of the box; I agree that the existing implementation is frankly: bad - it would have to be opt-in, though, to avoid regressions