Скрипт для шестнадцатеричного текстового конвертера ASCII - PullRequest
2 голосов
/ 06 апреля 2020

Я пытаюсь преобразовать шестнадцатеричное число в текст ASCII, и для этого я использовал xxd. Но проблема в том, что он не генерирует никаких выходных данных.

Например, я использовал:

echo 86973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D | xxd -r -p

, но это не дает мне никакого вывода.

Есть ли другие способ скрыть это без помощи онлайн-генератора? Пожалуйста, помогите !!

Ответы [ 3 ]

5 голосов
/ 06 апреля 2020

Ваши шестнадцатеричные данные имеют количество CR (0D) байтов, которые заставляют курсор перематываться на начало строки и перезаписывать любой предыдущий вывод. Кроме того, после завершения работы конвейера приглашение оболочки перезапишет все оставшиеся выходные данные.

Скорее всего, вы захотите преобразовать CR в LF, чтобы увидеть выходные данные, добавив | tr '\r' '\n' в конвейер:

$ echo 686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D | xxd -r -p | tr '\r' '\n'
history 
ls -ltr 
n netstats
n info 
n status
exit
3 голосов
/ 06 апреля 2020

Вы можете использовать printf и sed, чтобы разделить каждые 2 символа и вывести в любом формате, который вам нужен. Вы используете sed для создания списка строк из 2 символов, разделенных символом новой строки, и выводя в виде строки, вы избегаете проблем с преобразованием управляющих символов, например, 0D, et c ... Вы можете использовать printf "0x%s\n" ( который в результате обработки printf каждой строки ввода приведет к выводу всех двухзначных значений)

Например, вы можете сделать:

printf "0x%s\n" $(echo "686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D" |
sed 's/\(..\)/\1\n/g')

или эквивалент с a herestring (только bash)

printf "0x%s\n" $(sed 's/\(..\)/\1\n/g' <<< "686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D")

Выход

0x68
0x69
0x73
0x74
0x6F
0x72
0x79
0x20
0x0D
0x6C
0x73
0x20
0x2D
0x6C
0x74
0x72
0x20
0x0D
0x6E
0x20
0x6E
0x65
0x74
0x73
0x74
0x61
0x74
0x73
0x0D
0x6E
0x20
0x69
0x6E
0x66
0x6F
0x20
0x0D
0x6E
0x20
0x73
0x74
0x61
0x74
0x75
0x73
0x0D
0x65
0x78
0x69
0x74
0x0D

Если вы хотите значение в шестнадцатеричном нижнем регистре, тогда вы можете фактически обработать входные значения как шестнадцатеричные, используя "0x%02x" преобразование:

printf "0x%02x\n" $(echo "686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D" |
sed 's/\(..\)/0x\1\n/g')

Выход

0x68
0x69
0x73
0x74
0x6f
0x72
0x79
0x20
0x0d
0x6c
0x73
0x20
0x2d
0x6c
0x74
0x72
0x20
0x0d
0x6e
0x20
0x6e
0x65
0x74
0x73
0x74
0x61
0x74
0x73
0x0d
0x6e
0x20
0x69
0x6e
0x66
0x6f
0x20
0x0d
0x6e
0x20
0x73
0x74
0x61
0x74
0x75
0x73
0x0d
0x65
0x78
0x69
0x74
0x0d

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

Или - Если у меня он задом наперед, и вы действительно хотите значение ASCII для каждого символа в строке, вы можно использовать простые for l oop и printf для печати значения ASCII каждого символа. Чтобы вывести значение ASCII, перед именем переменной в двойных кавычках ставится одинарная кавычка, например,

a="686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D"
for ((i = 0; i < ${#a}; i++)); do printf "%s - 0x%02x\n" "${a:i:1}" "'${a:i:1}"; done

Выход

Символ и значение ASCII каждого символа :

6 - 0x36
8 - 0x38
6 - 0x36
9 - 0x39
7 - 0x37
3 - 0x33
7 - 0x37
4 - 0x34
6 - 0x36
F - 0x46
7 - 0x37
2 - 0x32
7 - 0x37
9 - 0x39
2 - 0x32
0 - 0x30
0 - 0x30
D - 0x44
6 - 0x36
C - 0x43
7 - 0x37
3 - 0x33
2 - 0x32
0 - 0x30
2 - 0x32
D - 0x44
6 - 0x36
C - 0x43
7 - 0x37
4 - 0x34
7 - 0x37
2 - 0x32
2 - 0x32
0 - 0x30
0 - 0x30
D - 0x44
6 - 0x36
E - 0x45
2 - 0x32
0 - 0x30
6 - 0x36
E - 0x45
6 - 0x36
5 - 0x35
7 - 0x37
4 - 0x34
7 - 0x37
3 - 0x33
7 - 0x37
4 - 0x34
6 - 0x36
1 - 0x31
7 - 0x37
4 - 0x34
7 - 0x37
3 - 0x33
0 - 0x30
D - 0x44
6 - 0x36
E - 0x45
2 - 0x32
0 - 0x30
6 - 0x36
9 - 0x39
6 - 0x36
E - 0x45
6 - 0x36
6 - 0x36
6 - 0x36
F - 0x46
2 - 0x32
0 - 0x30
0 - 0x30
D - 0x44
6 - 0x36
E - 0x45
2 - 0x32
0 - 0x30
7 - 0x37
3 - 0x33
7 - 0x37
4 - 0x34
6 - 0x36
1 - 0x31
7 - 0x37
4 - 0x34
7 - 0x37
5 - 0x35
7 - 0x37
3 - 0x33
0 - 0x30
D - 0x44
6 - 0x36
5 - 0x35
7 - 0x37
8 - 0x38
6 - 0x36
9 - 0x39
7 - 0x37
4 - 0x34
0 - 0x30
D - 0x44
0 голосов
/ 06 апреля 2020

Вы можете использовать python3 для печати символов ASCII. Это может не совпадать с выводом c xxd, как это делают другие ответы, но позволяет увидеть символы типа \ r \ n, которые вызывают проблемы.

$ str='686973746F7279200D6C73202D6C7472200D6E206E657473746174730D6E20696E666F200D6E207374617475730D657869740D'
$ python3 -c "b=b''.fromhex('$str'); s=str(b)[2:-1]; print(s)"
history \rls -ltr \rn netstats\rn info \rn status\rexit\r

Здесь

  • b=b''.fromhex('$str') преобразует шестнадцатеричные числа в байтовый объект. Если вы использовали python, для символа, такого как символ новой строки,
  • str(b)[2:-1] преобразует объект байтов, который выглядит как b'abcd', в abcd. b и ' s не важны для вывода и поэтому усекаются.
  • Если вы хотите заменить \r, как в ответе @ rtx13, добавьте s.replace('\r', '=n').

Дополнительные bash замечания по использованию

Возможно, вы получаете дополнительную новую строку в выходных данных при отправке на xxd. echo добавляет новую строку в вывод. Для демонстрации:

$ echo '' | xxd
00000000: 0a

Если вы не хотите добавлять байты в конвейер, используйте printf для более согласованного поведения .

...