Шестнадцатеричный: установить 8-битный байт в int

В Java:

У меня есть 32-битное число, данное мне в шестнадцатеричной форме. Мне дали конкретный номер байта (0-3, 0 для младшего байта) и сказали, что мне нужно заменить этот байт другим байтом, также предоставленным мне в шестнадцатеричной форме. Пример: 32-разрядное число 0xAAA5BBC6, замените байт 1 на 0x17, чтобы получить 0xAAA517C6.

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

Я считаю, что я должен использовать маскировку, но я не могу понять, с чего начать. Учитывая номер байта, как я могу изменить все 8 битов. Переключить один из них или включить легко, но переключить все 8 бит, чтобы получить определенное значение?

3 ответа

Решение

В одной строке, предполагая, что байты считаются из младшего байта:

int updatedValue = originalValue & ~(0xFF << (byteNumber << 3)) | ((((int)newByte) & 0xFF) << (byteNumber << 3));

Куда:
originalValue ваше оригинальное 32-битное целое
newByte это байт, который вам дан для замены старого байта
byteNumber это номер байта (0-3)

код делает следующее:

  • создайте маску для "удаления" старого байта (очистите биты этого байта). Для того, чтобы создать маску:

    • создать маску байта из всех установленных битов (все в 1) 0xFF
    • сместите эту маску в положение байта, который нужно "удалить", он должен быть в 8 раз больше количества байтов, которые нужно "удалить". Поскольку я не могу умножить (часть ваших ограничений), то я смещу это число на 3 бита влево (что эквивалентно умножению на 8, помните, что смещение битов на одну позицию влево равнозначно умножению на 2, поэтому смещение на 3 будет 2 * 2 * 2 = 8) это делается с помощью этого фрагмента кода: (byteNumber << 3)
    • "переключать" биты маски с ~Итак, у меня есть маска для "удаления" байта: ~(0xFF << (byteNumber << 3)) в этот момент ваша маска будет, скажем, FFFF00FF если вы хотите очистить байт #1
  • выполнить побитовую операцию между исходным номером и маской, созданной на первом шаге: ~(0xFF << (byteNumber << 3))

  • создайте 32-битное целое число с новым байтом и сместите его биты в позицию байта. Опять же, смещение сделано с (byteNumber << 3) который уже был объяснен.
  • выполнить побитовую или побитовую операцию с результатом второго шага, чтобы установить биты нового байта (это строка кода, последний шаг)

Теперь причина, по которой я делаю ((int)newByte) & 0xFF) вместо просто ((int)newByte)) или просто newByteявляется то, что JVM способствует int Оператор byte перед выполнением операции <<, это может иметь нежелательные последствия, если ваш newByte больше 0x7F (например, значение 0x80 будет брошен на int как 0xFFFFFF80 вместо 0x00000080). При выполнении ((int)newByte) & 0xFF) Я делаю повышение в int на всякий случай и очистить ненужные биты на всякий случай.

Взгляните на следующий пример:

input   =    AA      A5         BB      C6  (in hex)
input   = 10101010 10100101 10111011 11000110 (in binary)
mask    =    FF       FF       00       FF  (in hex)
mask    = 11111111 11111111 00000000 11111111 (in binary) 
-------------------------------------------------------
input   = 10101010 10100101 00000000 11000110 (bitwise AND)
replace =    FF       FF       17       FF  (in hex)
replace = 11111111 11111111 00010111 11111111 (in binary) 
-------------------------------------------------------
input   = 10101010 10100101 00010111 11000110 (bitwise OR)
input   =    AA      A5         17      C6  (in hex)

Последняя строка - ваш желаемый результат. Как видите, есть две побитовые операции, И и ИЛИ. Вы должны изучить это много, чтобы знать, как работают.

Как насчет того, чтобы создать метод (или конструктор класса), целью которого является именно анализ шестнадцатеричного значения и его преобразование в любой тип данных, который вы хотите. Я настоятельно рекомендую вам прочитать о переводе данных или посмотреть видео об этом на YouTube и посмотреть, как это может иметь отношение к вашему делу. Удачи! - Макс

Другие вопросы по тегам