web-dev-qa-db-fra.com

Conversion de Little Endian en Big Endian

Tout,

Je pratique des problèmes de codage en ligne. Je travaille actuellement sur un énoncé de problème Problems où nous devons convertir Big Endian <-> little endian. Mais je ne peux pas noter les étapes en considérant l'exemple donné comme suit: 

123456789 converts to 365779719

La logique que je considère est la suivante:
1> Obtenir la valeur entière (Depuis que je suis sur Windows x86, l'entrée est un petit boutien)
2> Génère la représentation hexadécimale de la même chose.
3> Inverser la représentation et générer la valeur entière big endian 

Mais je manque évidemment quelque chose ici. 

Quelqu'un peut-il me guider s'il vous plaît. Je code en Java 1.5

16
name_masked

Ce que vous devez réaliser, c’est que les échanges finaux traitent les octets qui représentent l’entier. Donc, le nombre de 4 octets 27 ressemble à 0x0000001B. Pour convertir ce nombre, il doit aller à 0x1B000000... Dans votre exemple, la représentation hexadécimale de 123456789 est 0x075BCD15, qui doit aller à 0x15CD5B07 ou sous la forme décimale 365779719.

La fonction Stacker posted déplace ces octets en les décalant un peu; plus spécifiquement, l'instruction i&0xff prend le plus bas octet de i, le << 24 le déplace alors de 24 bits, donc des positions 1-8 à 25-32. Donc, à travers chaque partie de l'expression.

Par exemple le code, jetez un oeil à this utility.

21
Bryan

Comme une grande partie du logiciel d’écriture consiste à réutiliser des solutions existantes, la première chose à faire devrait toujours être de regarder la documentation de votre langue/bibliothèque.

reverse = Integer.reverseBytes(x);

Je ne sais pas dans quelle mesure cette fonction est efficace, mais pour changer de nombre de chiffres, une ByteBuffer devrait offrir des performances décentes.

import Java.nio.ByteBuffer;
import Java.nio.ByteOrder;

...

int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);

buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);

buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);

Comme Eversor l'a souligné dans les commentaires, ByteBuffer.putInt() est une méthode facultative et peut ne pas être disponible sur toutes les implémentations Java.

L'approche DIY

La réponse de Stacker est très soignée, mais il est possible de l'améliorer. 

   reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;

Nous pouvons nous débarrasser des parenthèses en adaptant les bitmasks. E. g., (a & 0xFF)<<8 est équivalent à a<<8 & 0xFF00. Les parenthèses les plus à droite n'étaient de toute façon pas nécessaires.

   reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;

Comme le décalage à gauche est décalé de zéro bit, le premier masque est redondant. Nous pouvons nous débarrasser du masque le plus à droite en utilisant l'opérateur de décalage logique, qui ne déplace que dans zéro bit.

   reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;

Priorité des opérateurs ici, les détails sur les opérateurs de décalage sont dans le spécification du langage Java

26
Wolfram Schmied

Regarde ça 

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
25
stacker

Les classes wrapper primitives Java supportent l'inversion d'octets depuis 1.5 en utilisant la méthode reverseBytes.

Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)

Juste une contribution pour ceux qui recherchent cette réponse en 2018.

5
glf4k

la méthode suivante inverse l'ordre des bits dans une valeur d'octet:

public static byte reverseBitOrder(byte b) {
    int converted = 0x00;
    converted ^= (b & 0b1000_0000) >> 7;
    converted ^= (b & 0b0100_0000) >> 5;
    converted ^= (b & 0b0010_0000) >> 3;
    converted ^= (b & 0b0001_0000) >> 1;
    converted ^= (b & 0b0000_1000) << 1;
    converted ^= (b & 0b0000_0100) << 3;
    converted ^= (b & 0b0000_0010) << 5;
    converted ^= (b & 0b0000_0001) << 7;

    return (byte) (converted & 0xFF);
}
0
Lukas Z.

Je pense que cela peut aussi aider:

int littleToBig(int i)
{
    int b0,b1,b2,b3;

    b0 = (i&0x000000ff)>>0;
    b1 = (i&0x0000ff00)>>8;
    b2 = (i&0x00ff0000)>>16;
    b3 = (i&0xff000000)>>24;

    return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}
0
Venu