如何在Linux shell中将十六进制字符转换为ASCII字符?

如何在Linux shell中将十六进制字符转换为ASCII字符?,linux,bash,shell,encoding,scripting,Linux,Bash,Shell,Encoding,Scripting,假设我有一个字符串5a 这是ASCII字母Z的十六进制表示形式 我需要知道一个Linuxshell命令,它将接受一个十六进制字符串并输出该字符串所代表的ASCII字符 因此,如果我这样做: echo 5a | command_im_looking_for 我将看到一个单独的字母Z: Z 请注意,这不会跳过非十六进制字符。如果只需要十六进制(原始字符串中没有空格等): 另外,zsh和bash在echo中本机支持此功能: echo -e '\x5a' 根据“5a”的来源,您可以将\x附加到它并

假设我有一个字符串
5a

这是ASCII字母
Z
的十六进制表示形式

我需要知道一个Linuxshell命令,它将接受一个十六进制字符串并输出该字符串所代表的ASCII字符

因此,如果我这样做:

echo 5a | command_im_looking_for
我将看到一个单独的字母
Z

Z
请注意,这不会跳过非十六进制字符。如果只需要十六进制(原始字符串中没有空格等):

另外,
zsh
bash
echo
中本机支持此功能:

echo -e '\x5a'

根据“5a”的来源,您可以将\x附加到它并传递到printf

$ a=5a
$ a="\x${a}"
$ printf "$a"
Z

我以前用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不从标准输入读取数据。

您可以仅通过echo而不使用其他内容。不要伪造t添加“-n”,否则将自动获得换行符:

echo -n -e "\x5a"
GNU awk 4.1

awk -niord '$0=chr("0x"RT)' RS=.. ORS=
请注意,如果您对此进行响应,它将生成一个额外的空字节

$ echo 595a | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1c
0000000  59  5a  00
          Y   Z  \0
而是使用printf

$ printf 595a | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1c
0000000  59  5a
          Y   Z
还要注意,GNUawk默认生成UTF-8

$ printf a1 | awk -niord '$0=chr("0x"RT)' RS=.. ORS= | od -tx1
0000000 c2 a1
如果您正在处理ASCII以外的字符,您将 Base64编码结果字符串时,可以使用
-b

echo 5a | sha256sum | awk -bniord 'RT~/\w/,$0=chr("0x"RT)' RS=.. ORS=

下面是一个纯bash脚本(因为printf是bash内置的):

#警告:空格很重要
die(){echo“$@”>&2;退出1;}
p=48656C6F0A
测试$(${p}&1))==0 | |模具“长度为奇数”
p2='';对于((i=0;iBash-one-liner)

echo -n "5a" | while read -N2 code; do printf "\x$code"; done

dc可以在数字基之间转换:

$ echo 5a | (echo 16i; tr 'a-z' 'A-Z'; echo P) | dc
Z$

一些python3单行程序可以处理任意数量的字节

解码十六进制(带
条带
,这样就可以在stdin上换行):

编码十六进制:

$ echo foo | python3 -c "import sys, binascii; print(binascii.hexlify(sys.stdin.buffer.read()).decode())"
666f6f0a

与我的回答类似:

您可以使用与此相同的工具(使用ascii可打印字符而不是
5a
):

将产生以下结果:

abcd
根据,您可以使用
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
$printf 5a5a | perl-lne'打印包“H*”,$文件.bin
$perl-lne'打印解包“H*”,$\u'
有一个简单的shell命令“ascii”

如果你使用Ubuntu,只要

sudo apt install ascii
然后:

将输出:

ASCII 5/10 is decimal 090, hex 5a, octal 132, bits 01011010: prints as `Z'
Official name: Majuscule Z
Other names: Capital Z, Uppercase Z
对于较大的输入,可以使用此命令(python脚本):

echo 58595a | python -c "import sys; import binascii; print(binascii.unhexlify(sys.stdin.read().strip()).decode())"
结果将是:

XYZ
为了更简单,请定义一个别名:

alias hexdecoder='python -c "import sys; import binascii; print(binascii.unhexlify(sys.stdin.read().strip()).decode())"'

echo 58595a | hexdecoder

你可能需要在正则表达式后面加一个“i”。或者在字符类中加一个a-fA-F。我通常不喜欢perl,但这类东西做得很好。不过,如果你要转换大量数据,最好编写一个简短的C程序来实现这一点。更容易使用
perl-lne'打印包H*“,$\u'
echo-ne'\x5a'
是必需的,例如:如果没有echo的-n开关,将在Z之后输出新行('\x0a')。第二行和第三行可以折叠为一行:
printf'\x${a}"
print
更改为
sys.stdout.write
,以防止额外的换行字符。
溢出错误:Python int太大,无法转换为C long
或直接:printf'\x5a'@请确认您的评论应该解决我的答案的哪一方面?该死,我知道原始答案是3年后的事,但我没有线索xxd是存在的。就我现在遇到的问题而言,我一直需要它……调试器不断地以十六进制转储字节字符串。是的,@Vouze comment毫无意义。从xxd的手册页上看:“工具的古怪与其创建者的大脑相匹配。”所以xxd不是一个标准的shell工具,自1997年以来似乎就没有维护过;我不建议使用它。但是为什么不使用:a=5a;printf'\x'$a,它比sed表达式更简单。与其使用
“echo-n5a | xxd-r-p”
,我更愿意使用
“xxd-r-p”稍微短一点:
((i=0;我没有回答上面提出的问题,但回答了我在google send me here时搜索的问题:-)(顺便说一句,将输出发送到| hextump-C有助于识别不需要的换行符等。)很好,但这需要在每个十六进制对之前插入
\x
。示例是
5a
,但问题是如何将十六进制字符串转换为多个ASCII字符。只需在解码十六进制时使用print,您就可以看到ctrl字符、null字符,例如“echo 666f6f0a62617200 | python3-c”import sys,binascii;print(binascii.unexlify(input())“'输出:'b'foo\nbar\x00''这似乎不适用于多字节消息…当我运行
echo-n“0102abcd”|时,读取-n2代码;执行printf“\x$code“done | hextump
生成
0201 cdab
@John Steel Hextump似乎默认情况下以十六进制数字字显示数据。尝试此
echo-n“0102abcd”|读取-n2代码时;执行printf“\x$code”;done | hextump-e'/1”%02x“
$ printf 5a5a5a5a | perl -lne 'print pack "H*", $_' > file.bin
$ perl -lne 'print unpack "H*", $_' < file.bin
5a5a5a5a
sudo apt install ascii
ascii 0x5a
ASCII 5/10 is decimal 090, hex 5a, octal 132, bits 01011010: prints as `Z'
Official name: Majuscule Z
Other names: Capital Z, Uppercase Z
echo 58595a | python -c "import sys; import binascii; print(binascii.unhexlify(sys.stdin.read().strip()).decode())"
XYZ
alias hexdecoder='python -c "import sys; import binascii; print(binascii.unhexlify(sys.stdin.read().strip()).decode())"'

echo 58595a | hexdecoder