Как преобразовать шестнадцатеричные символы в символы ASCII в оболочке Linux? - PullRequest
56 голосов
/ 22 октября 2009

Допустим, у меня есть строка 5a.

Это шестнадцатеричное представление буквы ASCII Z.

Мне нужно знать команду оболочки Linux, которая будет принимать шестнадцатеричную строку и выводить символы ASCII, которые представляет строка.

Так что если я сделаю:

echo 5a | command_im_looking_for

Я увижу одиночное письмо Z:

Z

Ответы [ 12 ]

81 голосов
/ 07 октября 2011

Я делал это с помощью xxd

echo -n 5a | xxd -r -p

Но потом я понял, что в Debian / Ubuntu xxd является частью vim-common и, следовательно, может отсутствовать в минимальной системе. Чтобы также избежать perl (imho также не является частью минимальной системы), я использовал sed, xargs и printf следующим образом:

echo -n 5a | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf

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

57 голосов
/ 22 октября 2009
echo -n 5a | perl -pe 's/([0-9a-f]{2})/chr hex $1/gie'

Обратите внимание, что это не будет пропускать не шестнадцатеричные символы. Если вам нужен только шестнадцатеричный код (без пробелов в исходной строке и т. Д.):

echo 5a | perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie'

Кроме того, zsh и bash изначально поддерживают это в echo:

echo -e '\x5a'
13 голосов
/ 31 октября 2012

Вы можете сделать это только через эхо и без других вещей. Не забудьте добавить «-n», иначе вы получите автоматический перевод строки:

echo -n -e "\x5a"
9 голосов
/ 29 сентября 2014

Баш однострочный

echo -n "5a" | while read -N2 code; do printf "\x$code"; done
3 голосов
/ 22 октября 2009

в зависимости от того, где вы получили этот «5a», вы можете просто добавить \ x к нему и перейти к printf

$ a=5a
$ a="\x${a}"
$ printf "$a"
Z
2 голосов
/ 14 октября 2015

Некоторые однострочники python3, работающие с любым количеством байтов.

Декодирование в шестнадцатеричном формате (с strip, чтобы можно было использовать новую строку на stdin):

$ echo 666f6f0a | python3 -c "import sys, binascii; sys.stdout.buffer.write(binascii.unhexlify(input().strip()))"
foo

Шестнадцатеричное кодирование:

$ echo foo | python3 -c "import sys, binascii; print(binascii.hexlify(sys.stdin.buffer.read()).decode())"
666f6f0a
2 голосов
/ 30 декабря 2014

DC может конвертировать между числовыми основаниями:

$ echo 5a | (echo 16i; tr 'a-z' 'A-Z'; echo P) | dc
Z$
2 голосов
/ 08 сентября 2014

Вот чистый скрипт bash (так как printf - встроенный bash):

#warning : spaces do matter
die(){ echo "$@" >&2;exit 1;}

p=48656c6c6f0a

test $((${#p} & 1)) == 0 || die "length is odd"
p2=''; for ((i=0; i<${#p}; i+=2));do p2=$p2\\x${p:$i:2};done
printf "$p2"

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

1 голос
/ 22 октября 2009
echo 5a | python -c "import sys; print chr(int(sys.stdin.read(),base=16))"
0 голосов
/ 13 июля 2018

Согласно @ Рэндалу комментарию , вы можете использовать perl, например

$ printf 5a5a5a5a | perl -lne 'print pack "H*", $_'
ZZZZ

и наоборот:

$ printf ZZZZ | perl -lne 'print unpack "H*", $_'
5a5a5a5a

Другой пример с файлом:

$ printf 5a5a5a5a | perl -lne 'print pack "H*", $_' > file.bin
$ perl -lne 'print unpack "H*", $_' < file.bin
5a5a5a5a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...