2010-07-23 10 views
12

Rozważmy następujący test jednostkowy:Dlaczego Guid.ToString ("n") nie jest taki sam jak ciąg szesnastkowy generowany z tablicy bajtów tego samego identyfikatora 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(); 
    } 

Oto wynik:

Assert.AreEqual failed. Expected:<61772f3ae5de5f4a8577eb1003c5c054>. Actual:<3a2f7761dee54a5f8577eb1003c5c054>.

Odpowiedz

11

Dobrze, że są takie same, po pierwsze 4 bajty. A pierwsze cztery są takie same, tylko w odwrotnej kolejności.

Zasadniczo po utworzeniu z ciągu zakłada się, że jest w formacie "big-endian": Najwyższy bajt po lewej stronie. Jednak, gdy są przechowywane wewnętrznie (na maszynie Intel), bajty są sortowane "little-endian": bajt najwyższego rzędu po prawej.

12

Jeśli porównać wyniki, można zobaczyć, że trzy pierwsze grupy są odwrócone:

 
61 77 2f 3a e5 de 5f 4a 8577eb1003c5c054 
3a 2f 77 61 de e5 4a 5f 8577eb1003c5c054 

To dlatego, że w GUID structure te 3 grupy są zdefiniowane jako DWORD i dwóch WORD s zamiast bajtów:

{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} 

Tak więc w pamięci procesor Intel przechowuje je w kolejności Little-endian (najbardziej znaczący bajt na końcu).

4

Identyfikator GUID jest skonstruowany w następujący sposób:

int a 
short b 
short c 
byte[8] d 

Więc dla części reprezentowanej przez a kod dostaje bajty odwrócone. Wszystkie pozostałe części są przekształcane poprawnie.

+1

dlaczego "b" i "c" również nie zostały zmienione? – Sebastian

+0

@SebastianGodelet - ponieważ są one "krótkie" zamiast "int". – ChrisF

+1

Myślałem, że wszystko większe niż jeden bajt podlega zasadzie endianess: 'short s = 0xaf21;' może być przechowywane: | af | 21 | lub | 21 | af | – Sebastian