Преобразование Little Endian в Big Endian - PullRequest
17 голосов
/ 02 октября 2010

Все,

Я занимаюсь проблемами кодирования в Интернете.В настоящее время я работаю над постановкой задачи Задачи , где нам нужно преобразовать Big Endian <-> little endian.Но я не могу записать шаги, учитывая пример, приведенный в следующем виде:

123456789 converts to 365779719

Логика, которую я рассматриваю, такова:
1> Получить целочисленное значение (Так как я на Windows x86,input - Little endian)
2> Сгенерировать его шестнадцатеричное представление.
3> Обратно представить и сгенерировать целое значение с прямым порядком байтов

Но я, очевидно, что-то здесь упускаю

Может кто-нибудь, пожалуйста, направьте меня.Я кодирую в Java 1.5

Ответы [ 6 ]

27 голосов
/ 22 апреля 2015

Поскольку большая часть написания программного обеспечения связана с повторным использованием существующих решений, первым делом всегда следует заглядывать в документацию по вашему языку / библиотеке.

reverse = Integer.reverseBytes(x);

Я не знаю, насколько эффективна эта функция, но для переключения большого числа цифр ByteBuffer должен обеспечивать приличную производительность.

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);

Как отметил eversor в комментариях, ByteBuffer.putInt() является необязательным методом и может быть доступен не во всех реализациях Java.

Подход DIY

Ответ Укладчика довольно аккуратный, но его можно улучшить.

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

Мы можем избавиться от скобок, адаптируя битовые маски. Например, (a & 0xFF)<<8 эквивалентно a<<8 & 0xFF00. Правые скобки все равно не нужны.

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

Поскольку сдвиг влево сдвигается в нулевые биты, первая маска является избыточной. Мы можем избавиться от самой правой маски, используя оператор логического сдвига, который сдвигает только нулевые биты.

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

Приоритет оператора здесь, мельчайшие подробности об операторах сдвига находятся в Спецификации языка Java

25 голосов
/ 02 октября 2010

Проверьте это

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
21 голосов
/ 02 октября 2010

Вам нужно понять, что порядковые свопы имеют дело с байтами, которые представляют целое число. Таким образом, 4-байтовое число 27 выглядит как 0x0000001B. Чтобы преобразовать это число, нужно перейти к 0x1B000000 ... В вашем примере шестнадцатеричное представление 123456789 - 0x075BCD15, которое должно перейти к 0x15CD5B07 или в десятичной форме 365779719.

Размещенная функция Stacker перемещает эти байты, сдвигая их по битам; более конкретно, оператор i&0xff принимает младший байт из i, << 24 затем перемещает его на 24 бита вверх, с позиций 1-8 до 25-32. Так далее в каждой части выражения.

Например, код, посмотрите на эту утилиту.

6 голосов
/ 12 июля 2018

Примитивные классы-оболочки Java поддерживают обращение байтов начиная с 1.5 с использованием метода reverseBytes.

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

Просто вклад для тех, кто ищет этот ответ в 2018 году.

0 голосов
/ 31 октября 2013

следующий метод меняет порядок битов в байтовом значении:

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 голосов
/ 17 марта 2011

Я думаю, что это также может помочь:

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));
}
...