Подтвердить что ты не робот

Преобразование Little Endian в Big Endian

Все,

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

123456789 converts to 365779719

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

Но я, очевидно, что-то пропустил.

Кто-нибудь может направить меня. Я кодирую в Java 1.5

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Ответ 3

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

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;

Мы можем избавиться от круглых скобок, адаптируя битмаски. E. g., (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

Ответ 4

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

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

Ответ 5

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

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