2009-08-23 18 views
128

Necesito convertir un int a un byte[] una forma de hacerlo es usar BitConverter.GetBytes(). Pero im seguro si que coincide con la siguiente especificación:C# int to byte []

Un XDR entero de es un dato de 32 bits que codifica un número entero en el rango [-2147483648,2147483647]. El número entero se representa en notación complemento dos. Los bytes más y menos significativos son 0 y 3, respectivamente. Los enteros se declaran los siguientes:

Fuente: RFC1014 3.2

¿Cómo podría hacer un int para la transformación de bytes que satisfaga la especificación anterior?

+0

Esa es una buena pregunta. – ChaosPandion

Respuesta

168

El RFC solo intenta decir que un entero con signo es un entero normal de 4 bytes con bytes ordenados de una manera big-endian.

Ahora, probablemente esté trabajando en una máquina little-endian y BitConverter.GetBytes() le dará la byte[] invertida. Lo que podría intentar:

int intValue; 
byte[] intBytes = BitConverter.GetBytes(intValue); 
Array.Reverse(intBytes); 
byte[] result = intBytes; 

Para que el código sea más portátil, sin embargo, puede hacerlo de esta manera:

int intValue; 
byte[] intBytes = BitConverter.GetBytes(intValue); 
if (BitConverter.IsLittleEndian) 
    Array.Reverse(intBytes); 
byte[] result = intBytes; 
+3

O use ToArray. byte [] resultado = BitConverter.GetBytes (intValue) .Reverse(). ToArray(); –

19

BitConverter.GetBytes(int) casi hace lo que quiere, sino el orden de bits es incorrecto.

Usted puede utilizar el método IPAddress.HostToNetwork para intercambiar los bytes en el valor entero antes de usar o usar BitConverter.GetBytes Jon Skeet de EndianBitConverter class. Ambos métodos hacen lo correcto (tm) con respecto a la portabilidad.

int value; 
byte[] bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(value)); 
3

Cuando miro esta descripción, tengo la sensación de que este entero XDR es sólo un número entero big endian "estándar", pero ha expresado de la manera más ofuscado. Two's complement notation es mejor conocido como U2, y es lo que estamos usando en los procesadores de hoy. El orden de bytes indica que es una notación big-endian.
Respondiendo a su pregunta, debe invertir los elementos de su matriz (0 < -> 3, 1 < -> 2), ya que están codificados en little-endian. Para asegurarse, primero debe verificar BitConverter.IsLittleEndian para ver en qué máquina se está ejecutando.

30

Ésta es otra manera de hacerlo: como todos sabemos bytes 1x = 8x bits y, además, un entero "normal" (int32) contiene 32 bits (4 bytes). Podemos utilizar el operador >> desplazan los bits a la derecha (>> operador no cambia de valor.)

int intValue = 566; 

byte[] bytes = new byte[4]; 

bytes[0] = (byte)(intValue >> 24); 
bytes[1] = (byte)(intValue >> 16); 
bytes[2] = (byte)(intValue >> 8); 
bytes[3] = (byte)intValue; 

Console.WriteLine("{0} breaks down to : {1} {2} {3} {4}", 
    intValue, bytes[0], bytes[1], bytes[2], bytes[3]); 
+0

El inicializador de matriz y los bits xor (^) y '& 0xFF' son innecesarios. – dtb

+0

Sí, pero solo quería mostrar cómo funciona esto – Maciek

+5

Es big-endian, por lo que MSB se almacena primero, por lo que debe invertir sus índices. –

0
byte[] Take_Byte_Arr_From_Int(Int64 Source_Num) 
{ 
    Int64 Int64_Num = Source_Num; 
    byte Byte_Num; 
    byte[] Byte_Arr = new byte[8]; 
    for (int i = 0; i < 8; i++) 
    { 
     if (Source_Num > 255) 
     { 
     Int64_Num = Source_Num/256; 
     Byte_Num = (byte)(Source_Num - Int64_Num * 256); 
     } 
     else 
     { 
     Byte_Num = (byte)Int64_Num; 
     Int64_Num = 0; 
     } 
     Byte_Arr[i] = Byte_Num; 
     Source_Num = Int64_Num; 
    } 
    return (Byte_Arr); 
} 
+0

por favor, agregue más explicación –

+0

Gracias por la respuesta, ¿por qué eligió escribir una nueva implementación en lugar de utilizar el https://stackoverflow.com/a/1318948/58553? (¿Hay algún beneficio o inconveniente con su solución?) – Peter

+0

En caso de que el proyecto deba desarrollarse con no solo un idioma, puede ser útil realizar la similitud del código entre los idiomas en situaciones en las que se deben implementar ideas idénticas. De esta manera puede ayudar con los errores de captura. Seguro usando la función 'C#' 'BitConverter.GetBytes' con 'Endian' comprobando que todo lo que se necesita en la mayoría de los casos. Y más, en algunas situaciones, puede ocurrir que use la conversión no solo a Int32 (4 bytes) o Int64 (8 bytes) sino a otro número de bytes. Gracias. –

-1

¿Por qué todo este código en los ejemplos anteriores ...

una estructura con la disposición explícita actúa en ambos sentidos y no tiene ningún impacto en el rendimiento

[StructLayout(LayoutKind.Explicit)] 
struct IntByte 
{ 
    [FieldOffset(0)] 
    public int IntVal; 

    [FieldOffset(0)] 
    public byte B0; 
    [FieldOffset(1)] 
    public byte B1; 
    [FieldOffset(2)] 
    public byte B2; 
    [FieldOffset(3)] 
    public byte B3; 
} 
+0

¿Cómo usarías esto? y en segundo lugar, obtendrías el mismo resultado incluso si ejecutaras esto en 'big-endian' y en 'little-endian'. – Peter