在 bash 中进行 Ascii/Hex 转换

66

我现在正在这样做:

[root@~]# echo Aa|hexdump -v
0000000 6141 000a                              
0000003
[root@~]# echo -e "\x41\x41\x41\x41"
AAAA

但它的行为并不完全符合我的预期,

Aa 的十六进制形式应该是 4161,但输出结果是 6141 000a,这似乎没有意义。

在执行十六进制到 ASCII 转换时,是否有其他实用程序可以使我不需要前缀 \x


相关链接:https://dev59.com/nnE85IYBdhLWcg3wx2n2#2614831 - Ciro Santilli OurBigBook.com
相关链接:https://stackoverflow.com/questions/2614764/how-to-create-a-hex-dump-of-file-containing-only-the-hex-characters-without-spac/2614831#2614831 - undefined
15个回答

75
默认情况下,hexdump 打印的是16位整数,而不是字节。如果您的系统有这些工具,则hd(或hexdump -C)或xxd将提供更少令人惊讶的输出结果;如果没有,则od -t x1是一种获取逐字节十六进制输出的 POSIX 标准方式。您可以使用od -t x1c来显示字节十六进制值和相应的字母。
如果您有xxd(随 vim 一起提供),您可以使用xxd -r将其转换回十六进制(与xxd生成的格式相同)。如果您只有普通的十六进制(例如"4161",由xxd -p生成),您可以使用xxd -r -p进行转换。

xxd -p -r AAA,这个命令不起作用,它能直接从命令行中检索参数吗? - gdb
13
如果您想将“r”从十六进制转换回来,您需要使用类似于“echo 4161 | xxd -r -p”或“echo Aa | xxd -p”这样的命令。 - Random832
只是提醒一下,目前 xxd 已经出现了问题。它显示的是所有零而不是数据。可能是特定于我的设置(xxd 2021-10-22,Ubuntu 22.04,大于2GB的大文件),但无论如何,您都应该意识到这一点(我浪费了一些时间来弄清楚发生了什么)。 - midenok

31

对于第一部分,请尝试

echo Aa | od -t x1

它按字节打印

$ echo Aa | od -t x1
0000000 41 61 0a
0000003
0a 是echo产生的隐式换行符。 请改用echo -nprintf代替。
$ printf Aa | od -t x1
0000000 41 61
0000002

2
如何将十六进制转换回ASCII? - gdb
example: echo -e "\x68" - cary

23

对于单行解决方案:

echo "Hello World" | xxd -ps -c 200 | tr -d '\n'

它将打印:

48656c6c6f20576f726c640a

或者用于文件:

cat /path/to/file | xxd -ps -c 200 | tr -d '\n'

用于反向操作:

echo '48656c6c6f20576f726c640a' | xxd -ps -r

它将打印:

Hello World

23
$> printf "%x%x\n" "'A" "'a"
4161

1
@gdb:请参考printf中的说明:“如果前导字符是单引号或双引号,则该值应为紧随其后的字符在底层代码集中的数值。” - Dennis Williamson
2
这里的C风格printf解决方案应该被接受作为答案。它是最便携和最简单的,而且符合POSIX标准,不需要可能可用或不可用的外部工具。 - Yokai

4

使用bash:

a=abcdefghij    
for ((i=0;i<${#a};i++));do printf %02X \'${a:$i:1};done

6162636465666768696A


一些字符(如空格、制表符、\r、\n)的输出结果错误,所有这些字符都将显示为\x00。 - Giac

4

我使用:

> echo Aa | tr -d '\n' | xxd -p
4161

> echo 414161 | tr -d '\n' | xxd -r -p
AAa
< p > tr -d '\n'会修剪输入中可能存在的任何换行符

结果: tr -d '\n'命令将删除输入中的任何换行符。

1
在 macOS 上,您也可以使用 echo -n Aa,而不是 echo Aa | tr -d '\n' - p13rr0m
2
@p13rr0m 你说得对,它也应该在所有*nix系统上运行。 - stelios

2
Text2Conv="Aa"
for letter in $(echo "$Text2Conv" | sed "s/\(.\)/'\1 /g");do printf '%x' "$letter";done

4161

使用sed将Text2Conv解析为我们可以分离并循环使用for的格式是关键。


2

终于得到了正确的东西

echo "Hello, world!" | tr -d '\n' | xxd -ps -c 200

2
echo -n "Hello, world!" | xxd -ps -c 200 也可以工作。 - Casey Flynn
2
我通常使用 xxd -ps -c 200 <<< "Hello, world!" - ssc

2

我不知道它看起来有多疯狂,但它确实非常有效

ascii2hex(){ a="$@";s=0000000;printf "$a" | hexdump | grep "^$s"| sed s/' '//g| sed s/^$s//;}

当我尝试在十六进制中看到我的名字时,创建了这个东西 ;) 使用方法:如何使用它:)


1

这是我写的一个小脚本,用于将ASCII转换为十六进制。希望能有所帮助:

echo '0x'"`echo 'ASCII INPUT GOES HERE' | hexdump -vC |  awk 'BEGIN {IFS="\t"} {$1=""; print }' | awk '{sub(/\|.*/,"")}1'  | tr -d '\n' | tr -d ' '`" | rev | cut -c 3- | rev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接