Можно ли использовать xxd для вывода двоичного представления шестнадцатеричного числа, а не строки?

10

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

Вот что сейчас происходит:

echo '0A' | xxd  -b
0000000: 00110000 01000001 00001010

Что я хотел бы иметь:

echo '0A' | xxd  -b
0000000: 00001010    

или

echo '0A' | xxd  -b
0000000: 01010000    

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

TheMeaningfulEngineer
источник

Ответы:

9

echo '0A'производит три символа 0 A NL:; xxd -bзатем напечатает эти три символа в двоичном формате. Если вам нужен только один байт со значением 10 (то есть шестнадцатеричный A), вы можете написать (в bash):

echo -n $'\x0A'
      ^ ^  ^
      | |  |
      | |  +-- `\x` indicates a hexadecimal escape
      | +----- Inside a $' string, escapes are interpreted
      +------- -n suppresses the trailing newline

Лучшая альтернатива была бы printf '\x0A'; printf интерпретирует escape-последовательности в строке формата и не выводит неявные символы новой строки. (Это Posix-совместимое решение, которое должно работать на любой Posix-совместимой оболочке.) Еще одна возможность bash есть echo -n -e '\x0A'; (нестандартный) -eфлаг запрашивает эхо для интерпретации escape-последовательностей.

echo '1' | xxd -bне выведет эквивалент гекса 50, потому xxdчто не знает, что 0Aэто шестнадцатеричное число, а 1это не так. Кроме того, код ascii для символа 1является шестнадцатеричным 31, а не 50.

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

RICi
источник
Извините за 50. Это опечатка. Исправление это сейчас
TheMeaningfulEngineer
7

Если вы хотите двоичный выход для строки шестнадцатеричных цифр, xxd -r -p. Например:

 $ echo '0A0B0C0D' | xxd -r -p | xxd -b
 0000000: 00001010 00001011 00001100 00001101                    ....

преобразует 0A0B0C0D в четыре байта двоичного файла (первый вызов xxd), а затем преобразует его обратно для печати (второй вызов). Вы говорите, что хотите двоичный вывод, но примеры, которые вы пытаетесь использовать, являются печатным представлением.

Я не знаю ничего, где порядок байтов на уровне клевов неоднозначен, как вы подразумеваете в своем втором примере. Преобразование в xxd является чистым байтом за раз, не предполагая, что они представляют какое-то конкретное многобайтовое число.

jtniehof
источник
2

Да, вы можете использовать xxdэто, но вам может не понравиться формат ввода. В вашем примере 0x0a - это шестнадцатеричное значение новой строки ASCII. Вы можете создать файл с одной новой строкой, а затем использовать xxdдля создания списка:

$ xxd one_line_file
0000000: 0a                                       .

Вы можете получить одну новую строку xxdиз этого вывода, если вы установите для нее правильные флаги:

$ echo "0000000: 0a" | xxd -r > another_one_line_file
$ xxd another_one_line_file
0000000: 0a 

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

Брюс Эдигер
источник