2010-08-03 19 views
7

Así que estaba usando BitConverter.GetBytes() para convertir uint32 a byte [], pero mi el orden de la matriz parece ser al revés. http://msdn.microsoft.com/en-us/library/1184xdy4.aspx (muestra que es byte [] parece ser poco endian).C# - Conversión a uint byte []

¿Hay una mejor manera de manejar esto que simplemente usar LINQ para revertir las matrices de bytes?

+0

supongo que es donde estoy confundido, aunque ya BitConverter.IsLittleEndian devuelve falso, pero BitConverter.GetBytes() devuelve pequeñas matrices endian. –

+0

Si esto es Windows, BitConverter.IsLittleEndian que devuelve falso es claramente un error, ya que los procesadores x86 y x86-64 son Little Endian. – Powerlord

Respuesta

0

Entonces me di cuenta de una gran parte de mi confusión se relaciona con esto: IsLittleEndian field reports false, but it must be Little-Endian?

Lo que terminé haciendo fue envolviendo todo el BitConverter llamadas con llamada que tuvo un parámetro adicional para specifiy orden de bits, a continuación, se agregó una función que se llama para verificar si los bytes deben ser reverenciados.

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 para cambiar el endianess.

4

Microsoft discute el/tema ascendente hacia la izquierda bigEndian con los GetBytes (método) en la página de documentación para BitConverter.

2

Si van a estar moviéndose entre arquitecturas de plataforma simplemente invirtiendo la matriz podría ser correcta en una plataforma, pero fallan en una plataforma que ya está utilizando big endian.

utiliza el IPAddress.HostToNetworkOrder funciones, lo que asegurará que los datos están siempre en el orden de red (big endian).

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

El siguiente es un método para obtener siempre la matriz de bytes de Big Endian rápidamente.

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); 
    } 

Esta sobrecarga puede ser útil, aunque se debe tener cuidado cuando se trabaja a través de máquinas con diferentes endian-sas.

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