Почему Guid.ToString("n") не совпадает с шестнадцатеричной строкой, сгенерированной из байтового массива того же guid?
Рассмотрим следующий модульный тест:
[TestMethod]
public void TestByteToString()
{
var guid = new Guid("61772f3ae5de5f4a8577eb1003c5c054");
var guidString = guid.ToString("n");
var byteString = ToHexString(guid.ToByteArray());
Assert.AreEqual(guidString, byteString);
}
private String ToHexString(Byte[] bytes)
{
var hex = new StringBuilder(bytes.Length * 2);
foreach(var b in bytes)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
Вот результат:
Assert.AreEqual failed. Expected:<61772f3ae5de5f4a8577eb1003c5c054>. Actual:<3a2f7761dee54a5f8577eb1003c5c054>.
3 ответа
Ну, они одинаковые, после первых 4 байтов. И первые четыре одинаковые, только в обратном порядке.
По сути, при создании из строки предполагается, что она имеет формат "big-endian": старший байт слева. Однако при внутреннем хранении (на машине Intel-ish) байты располагаются в порядке "little-endian": байт высшего порядка справа.
Если вы сравните результаты, вы увидите, что первые три группы перевернуты:
61 77 2f 3a e5 de 5f 4a 8577eb1003c5c054 3a 2f 77 61 de e5 4a 5f 8577eb1003c5c054
Это потому, что в структуре GUID эти 3 группы определены как DWORD
и два WORD
s, а не байты:
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
поэтому в памяти процессор Intel хранит их в порядке старшего байта (самый старший байт последнего).
GUID имеет следующую структуру:
int a
short b
short c
byte[8] d
Так что для части, представленной a
Ваш код возвращает байты в обратном порядке. Все остальные части преобразованы правильно.