2010-08-03 14 views
7

Użyłem więc BitConverter.GetBytes() do konwersji uint32 na bajt [], ale moja kolejność w tablicy wydaje się być wsteczna. http://msdn.microsoft.com/en-us/library/1184xdy4.aspx (pokazuje, że jego bajt [] wydaje się być małym endianem).C# - Konwersja uint na bajt []

Czy jest lepszy sposób na to, niż tylko użycie linq do odwrócenia tablic bajtów?

+0

myślę, że to, gdzie jestem mylić choć od BitConverter.IsLittleEndian zwraca false, ale BitConverter.GetBytes() zwraca małe tablice endian. –

+0

Jeśli jest to system Windows, BitConverter.IsLittleEndian, zwracając wartość false, jest oczywiście błędem, ponieważ procesory x86 i x86-64 to Little Endian. – Powerlord

Odpowiedz

0

więc zorientowali się duża część mojego zamieszania jest związane to: IsLittleEndian field reports false, but it must be Little-Endian?

Co skończyło się robi został zawijania cały BitConverter domaga się rozmowy, które miały dodatkowy parametr do specifiy bajt, a następnie dodano funkcję, która jest wywoływana w celu sprawdzenia, czy bajty muszą być czczone.

public static class BitEndianConverter 
{ 
    public static byte[] GetBytes(bool value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 

    public static byte[] GetBytes(char value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(double value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(float value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(int value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(long value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(short value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(uint value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(ulong value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 
    public static byte[] GetBytes(ushort value, bool littleEndian) 
    { 
     return ReverseAsNeeded(BitConverter.GetBytes(value), littleEndian); 
    } 

    private static byte[] ReverseAsNeeded(byte[] bytes, bool wantsLittleEndian) 
    { 
     if (wantsLittleEndian == BitConverter.IsLittleEndian) 
      return bytes; 
     else 
      return (byte[])bytes.Reverse().ToArray(); 
    } 
} 
5

Array.Reverse zmienić wartość końcową.

4

Firma Microsoft omawia problem małego-endian/big-endian za pomocą metody GetBytes() na stronie dokumentacji dla BitConverter.

2

Jeśli zamierzasz poruszać się między architekturami platform, po prostu odwrócenie tablicy może być poprawne na jednej platformie, ale niepowodzenie na platformie, która już używa dużego endianu.

Używa się funkcji IPAddress.HostToNetworkOrder, które zapewniają, że dane są zawsze w porządku sieciowym (duży endian).

uint number = 234234233; 
uint bigEndian = IPAddress.HostToNetworkOrder(number); 
byte[] b = BitConverter.GetBytes(bigEndian); 
1

Poniżej znajduje się metoda, aby szybko uzyskać dużą tablicę bajtów endianowych.

public static byte[] GetBigEndianBytes(UInt32 val, bool isLittleEndian) 
    { 
     UInt32 bigEndian = val; 
     if (isLittleEndian) 
     { 
      bigEndian = (val & 0x000000FFU) << 24 | (val & 0x0000FF00U) << 8 | 
       (val & 0x00FF0000U) >> 8 | (val & 0xFF000000U) >> 24; 
     } 
     return BitConverter.GetBytes(bigEndian); 
    } 

To przeciążenie może być przydatny, choć należy zachować ostrożność podczas pracy na komputerach z różnymi endian-nesses.

public static byte[] GetBigEndianBytes(UInt32 val) 
    { 
     return GetBigEndianBytes(val, BitConverter.IsLittleEndian); 
    }