我想将二进制数据转换成十六进制,只需要简单的转换,不需要任何花哨的格式化。使用 hexdump
命令过于复杂,会给我做很多"过度格式化"的处理。我希望能够从 /dev/random 文件中取出 x 字节的数据并将其转换为十六进制数。
最好只使用标准的 Linux 工具,这样我就不需要在每台机器上都安装工具(因为机器数量很多)。
我想将二进制数据转换成十六进制,只需要简单的转换,不需要任何花哨的格式化。使用 hexdump
命令过于复杂,会给我做很多"过度格式化"的处理。我希望能够从 /dev/random 文件中取出 x 字节的数据并将其转换为十六进制数。
最好只使用标准的 Linux 工具,这样我就不需要在每台机器上都安装工具(因为机器数量很多)。
也许可以使用xxd
:
% xxd -l 16 -p /dev/random
193f6c54814f0576bc27d51ab39081dc
time xxd -c 32 -l 1024000000 -ps /dev/urandom 32bytehexnewtest1.txt ; real 0m17.484s
- cigol on小心!
hexdump
和xxd
以不同的字节序列输出结果!
$ echo -n $'\x12\x34' | xxd -p
1234
$ echo -n $'\x12\x34' | hexdump -e '"%x"'
3412
简单解释。大端序和小端序 :D
echo -n $'\x12\x34' | hexdump -e '/1 "%x"'
可以得到相同的字节序。 - user2350426hexdump
命令会去掉前导零。 - Edward Ned Harvey使用 od 命令(适用于GNU系统):
$ echo abc | od -A n -v -t x1 | tr -d ' \n'
6162630a
$ echo abc | hexdump -ve '/1 "%02x"'
6162630a
根据您的系统类型,这两个实用程序中的一个或两个都将可用--BSD系统将od弃用为hexdump,GNU系统则相反。
也许你可以自己用C编写一个小工具,并即时编译它:
int main (void) {
unsigned char data[1024];
size_t numread, i;
while ((numread = read(0, data, 1024)) > 0) {
for (i = 0; i < numread; i++) {
printf("%02x ", data[i]);
}
}
return 0;
}
然后从标准输入中提供数据:
cat /bin/ls | ./a.out
你甚至可以使用heredoc语法将这个小的C程序嵌入到shell脚本中。
所有的解决方法似乎都很难记住或过于复杂。我发现使用 printf
是最简短的方法:
$ printf '%x\n' 256
100
但是正如评论中所指出的那样,这不是作者想要的,为了公平起见,下面是完整的答案。
... 使用上述内容以输出实际的二进制数据流:
printf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)
它的作用:
printf '%x\n'
- 打印一个整数序列,例如printf '%x,' 1 2 3
,将会打印1,2,3,
$(...)
- 这是一种获取某些Shell命令输出并处理它的方法cat /dev/urandom
- 它输出随机的二进制数据head -c 5
- 将二进制数据限制在5个字节以内od -An -vtu1
- 八进制转储命令,将二进制转换为十进制作为测试案例('a'是61进制,'p'是70进制,...):
$ printf '%x\n' $(echo "apple" | head -c 5 | od -An -vtu1)
61
70
70
6c
65
或者想要测试单个二进制字节,可以在输入时给出十进制的61('='字符)来生成二进制数据('\\x%x'
格式可以实现此功能)。上述命令将正确输出 3d(十进制61):
$printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1)
3d
printf '%x\n' $(head -c 5 /dev/urandom | od -An -vtu1)
或者是有特定的原因需要使用cat命令吗?另外,如果你想要在结尾只用一个新行分隔十六进制,我想到了这个echo $(printf "%x" $(head -c 5 /dev/urandom | od -An -vtu1))
虽然我不知道这些的性能成本,主要是为什么我问是否可以去掉cat命令。我对命令行还很陌生,但这些信息都很有帮助。 - cigol ontime
命令来测量命令的性能。 - marcinjprintf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)
相比之下,第二条命令没有使用cat管道,速度更快一些。
printf '%x\n' $(head -c 5 /dev/urandom | od -An -vtu1)
- cigol on如果你需要一个没有换行符的大数据流,你可以使用 tr
和 xxd
(Vim 的一部分)进行逐字节转换。
head -c1024 /dev/urandom | xxd -p | tr -d $'\n'
或者您可以使用 hexdump
(POSIX) 进行逐字转换。
head -c1024 /dev/urandom | hexdump '-e"%x"'
echo abc | hexdump -e '/1 "%02x"'
命令获取网络顺序和 0x0a
的值为 0。 - user2350426如果你的目标平台不止一个,那么Perl5在可移植性方面可能更有效。它随附于每个Linux发行版和Unix操作系统中。通常可以在容器镜像中找到它,而其他工具(如xxd或hexdump)则不可用。以下是如何使用Perl执行相同操作的方法:
$ head -c8 /dev/urandom | perl -0777 -ne 'print unpack "H*"'
5c9ed169dabf33ab
$ echo -n $'\x01\x23\xff' | perl -0777 -ne 'print unpack "H*"'
0123ff
$ echo abc | perl -0777 -ne 'print unpack "H*"'
6162630a
n=12
echo "$a" | xxd -l "$n" -p
echo "$a" | od -N "$n" -An -tx1 | tr -d " \n" ; echo
echo "$a" | hexdump -n "$n" -e '/1 "%02x"'; echo
n=12
,$a
是从1到26的字节值:a="$(printf '%b' "$(printf '\\0%o' {1..26})")"
这可以用来在每个程序中获取$n
个随机字节值:
xxd -l "$n" -p /dev/urandom
od -vN "$n" -An -tx1 /dev/urandom | tr -d " \n" ; echo
hexdump -vn "$n" -e '/1 "%02x"' /dev/urandom ; echo