2010-02-28 4 views
21

J'ai cette fonction en C# pour convertir un petit tableau d'octets endian à un nombre entier:Comment convertir un int en un petit tableau d'octets endian?

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

Maintenant, je veux reconvertir en little endian .. Quelque chose comme

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

Tous idée?

Merci.

Répondre

17

inverse Il suffit, Notez que ce code (comme l'autre) ne fonctionne que sur une petite machine Endian. (modifier - qui a eu tort, puisque ce code renvoie LE par définition)

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

Pourquoi votre travail par exemple que sur un petit machine -endienne?AFAIK la méthode de décalage de bits devrait être endian-agnostique. – nonoitall

+0

@John, je suis à peu près sûr que le code fonctionne bien que le code fonctionne sur une architecture big- ou little-endian. Dans les deux cas, b [0] est l'octet d'ordre le plus bas, b [1] est l'octet d'ordre le plus bas, et ainsi de suite. –

+0

Mon erreur, puisque ce code renvoie LE plutôt que l'ordre naturel des octets du cpu sous-jacent, il fonctionnera sur toutes les architectures. Je vais supprimer le texte incorrect. –

7

suffit de le faire dans le sens inverse:

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

Pouvez-vous utiliser la classe BitConverter? Il ne fonctionnera que sur le petit matériel endian je crois, mais il devrait gérer la plupart des charges lourdes pour vous.

Voici un exemple artificiel qui illustre l'utilisation de la classe:

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

En fonction de ce que vous êtes en train de faire, vous pouvez compter sur laisser le cadre gérer les détails de boutisme pour vous en utilisant IPAddress.HostToNetworkOrder et la fonction inverse correspondante. Ensuite, utilisez simplement la classe BitConverter pour aller vers et depuis les tableaux d'octets.

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 peut être utilisé pour cela, et bien sûr, il peut également être utilisé sur les deux systèmes endian petits et grands.

Bien sûr, vous devrez suivre l'endianness de vos données. Pour les communications par exemple, cela serait défini dans votre protocole.

Vous pouvez alors utiliser la classe BitConverter pour convertir un type de données dans un tableau d'octets et vice-versa, puis utilisez le drapeau IsLittleEndian pour voir si vous avez besoin de le convertir sur votre système ou non.

Le drapeau IsLittleEndian vous dira la boutisme du système, de sorte que vous pouvez l'utiliser comme suit:

Ceci est de la page MSDN sur la 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. 

Vous pouvez trouver l'article complet here.

Hope this helps quelqu'un venir ici :)

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

Pourriez-vous s'il vous plaît expliquer pourquoi cela aiderait? –

+0

Je suis presque sûr que c'est en cas de machine Big Endian. – Vassilis

0

Vous pouvez utiliser cette option si vous ne souhaitez pas utiliser de nouvelles allocations de tas:

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