2009-11-04 3 views
3

Tout d'abord, je pense que cette question n'est pas indépendante de C#. Mais peut également être utilisé dans d'autres langues comme C.Conversion de little endian en int


J'essaie maintenant d'analyser un format de fichier qui stocke des entiers dans 4 octets de format petit-boutiste. TBH, je ne sais pas comment fonctionne le format little-endian ni le format big-endian. Mais j'ai besoin de les convertir en une variable int utilisable.

Par exemple, 02 00 00 00 = 2

Jusqu'à présent, j'ai ce code pour convertir les 2 premiers octets: (je FileStream.Read pour stocker les données brutes en une variable tampon)

 int num = ((buffer[5] << 8) + buffer[4]); 

Mais il ne convertira que les deux premiers octets. (02 00 dans l'exemple, pas 02 00 00 00)

Toute aide serait appréciée :)

Répondre

14
int GetBigEndianIntegerFromByteArray(byte[] data, int startIndex) { 
    return (data[startIndex] << 24) 
     | (data[startIndex + 1] << 16) 
     | (data[startIndex + 2] << 8) 
     | data[startIndex + 3]; 
} 

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

'(données [startIndex + 3] << 24) | (data [startIndex + 2] << 16) '- Pourquoi cela fonctionne-t-il? – alex

2

IIRC, la bibliothèque de Jon Skeet MiscUtil a un code pour le traitement endian-ness.

4

en utilisant des méthodes intégrées:

byte[] data = { 2, 0, 0, 0 }; 
Array.Reverse(data); 
int value = BitConverter.ToInt32(data, 0); 

De l'autre côté du spectre, en utilisant de code optimisé dangereux:

public static unsafe void SwapInts(int[] data) { 
    int cnt = data.Length; 
    fixed (int* d = data) { 
    byte* p = (byte*)d; 
    while (cnt-- > 0) { 
     byte a = *p; 
     p++; 
     byte b = *p; 
     *p = *(p + 1); 
     p++; 
     *p = b; 
     p++; 
     *(p - 3) = *p; 
     *p = a; 
     p++; 
    } 
    } 
} 

Remarque: Vous pouvez utiliser le BitConverter.IsLittleEndian pour vérifier si l'ordinateur utilise intérieurement le petit boutiste ou le gros boutiste, de sorte que vous pouvez rendre le code portable.

0

ma solution universelle de little endian int est la suivante:

public static int GetLittleEndianIntegerFromByteArray(byte[] data) 
{ 
    int length = data.Length; 
    int result = 0; 

    for (int i = length - 1; i >= 0; i--) 
    { 
     result |= data[i] << i * 8; 
    } 
    return result; 
} 
Questions connexes