2010-02-28 4 views
21

Ho questa funzione in C# per convertire un po 'di array di endian byte in un numero intero:Come convertire un int in un array di byte little endian?

int LE2INT(byte[] data) 
{ 
    return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]; 
} 

Ora voglio riconvertirlo in little endian .. Qualcosa di simile

byte[] INT2LE(int data) 
{ 
    // ... 
} 

Qualsiasi idea?

Grazie.

risposta

17

Basta invertire tale tendenza, Si noti che questo questo codice (come gli altri) funziona solo su una piccola macchina Endian. (modifica - che era sbagliato, dal momento che questo codice restituisce LE per definizione)

byte[] INT2LE(int data) 
    { 
    byte[] b = new byte[4]; 
    b[0] = (byte)data; 
    b[1] = (byte)(((uint)data >> 8) & 0xFF); 
    b[2] = (byte)(((uint)data >> 16) & 0xFF); 
    b[3] = (byte)(((uint)data >> 24) & 0xFF); 
    return b; 
    } 
+5

Perché dovrebbe tuo esempio funziona solo su un po ' macchina -endiana?AFAIK il metodo di spostamento del bit dovrebbe essere endnostico-agnostico. – nonoitall

+0

@ John, sono abbastanza sicuro che il codice funzioni bene se il codice gira su un'architettura big o little-endian. In entrambi i casi, b [0] è il byte di ordine più basso, b [1] è il byte dell'ordine successivo più basso e così via. –

+0

Errore mio, poiché questo codice restituisce LE anziché l'ordine di byte naturale della CPU sottostante, funzionerà su tutte le architetture. Rimuoverò il testo errato. –

7

Just do it in senso inverso:

result[3]= (data >> 24) & 0xff; 
result[2]= (data >> 16) & 0xff; 
result[1]= (data >> 8) & 0xff; 
result[0]= data  & 0xff; 
3

Potrebbe utilizzare la classe BitConverter? Credo che funzionerà solo su hardware little endian, ma dovrebbe gestire la maggior parte del lavoro pesante per te.

Il seguente è un esempio forzato che illustra l'utilizzo della classe:

 if(BitConverter.IsLittleEndian) 
     { 
      int someInteger = 100; 
      byte[] bytes = BitConverter.GetBytes(someInteger); 
      int convertedFromBytes = BitConverter.ToInt32(bytes, 0); 
     } 
0

A seconda di cosa si sta effettivamente facendo, si poteva contare sul lasciare gestire il quadro i dettagli di endianness per voi utilizzando IPAddress.HostToNetworkOrder e la funzione di inversione corrispondente. Quindi basta usare la classe BitConverter per andare ae da matrici di byte.

1
public static string decimalToHexLittleEndian(int _iValue, int _iBytes) 
    { 
     string sBigEndian = String.Format("{0:x" + (2 * _iBytes).ToString() + "}", _iValue); 
     string sLittleEndian = ""; 

     for (int i = _iBytes - 1; i >= 0; i--) 
     { 
      sLittleEndian += sBigEndian.Substring(i * 2, 2); 
     } 

     return sLittleEndian; 
    } 
15

La classe BitConverter può essere utilizzato per questo, e, naturalmente, può essere usato anche su entrambi i sistemi piccoli e grandi endian.

Ovviamente, dovrai tenere traccia dello endianness dei tuoi dati. Per le comunicazioni, ad esempio, questo sarebbe definito nel tuo protocollo.

È quindi possibile utilizzare la classe BitConverter per convertire un tipo di dati in un array di byte e viceversa, quindi utilizzare il flag IsLittleEndian per verificare se è necessario convertirlo sul sistema o meno.

La bandiera IsLittleEndian vi dirà la endianness del sistema, in modo da poter utilizzare nel modo seguente:

Questo è dalla pagina MSDN sulla classe BitConverter.

int value = 12345678; //your value 
    //Your value in bytes... in your system's endianness (let's say: little endian) 
    byte[] bytes = BitConverter.GetBytes(value); 
    //Then, if we need big endian for our protocol for instance, 
    //Just check if you need to convert it or not: 
    if (BitConverter.IsLittleEndian) 
    Array.Reverse(bytes); //reverse it so we get big endian. 

È possibile trovare l'articolo completo here.

Spero che questo aiuti chiunque venendo qui :)

1
BitConverter.GetBytes(1000).Reverse<byte>().ToArray(); 
+1

Potresti spiegare perché questo potrebbe essere d'aiuto? –

+0

Sono abbastanza sicuro che questo è nel caso della macchina Big Endian. – Vassilis

0

È possibile utilizzare questo se non si desidera utilizzare nuove allocazioni di heap:

public static void Int32ToFourBytes(Int32 number, out byte b0, out byte b1, out byte b2, out byte b3) 
{ 
    b3 = (byte)number; 
    b2 = (byte)(((uint)number >> 8) & 0xFF); 
    b1 = (byte)(((uint)number >> 16) & 0xFF); 
    b0 = (byte)(((uint)number >> 24) & 0xFF); 
}