添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在shell脚本中把二进制数据转换成十六进制

67 人关注

我想把二进制数据转换为十六进制,就是这样,没有花哨的格式化和所有的东西。 hexdump 似乎太聪明了,对我来说,它 "过度格式化"。我想从/dev/random中获取x个字节,并将其作为十六进制传递。

最好我只使用标准的Linux工具,这样我就不需要在每台机器上安装它(有很多)。

2 个评论
我不得不使用/dev/urandom,/dev/random只是冻结了。
@AquariusPower 当它没有足够的随机数据时,就会出现随机块,而Urandom则不会(IIRC在它拥有的数据上循环)。
linux
scripting
hexdump
davka
davka
发布于 2011-06-09
9 个回答
unutbu
unutbu
发布于 2015-11-16
已采纳
0 人赞同

也许使用 xxd

% xxd -l 16 -p /dev/random
193f6c54814f0576bc27d51ab39081dc
    
xxd是vim的一部分,所以它可能不总是被安装。
注意,你可以使用 -c 来改变每行的字节数。 不幸的是,你只能将其设置为256,之后你需要有一些换行。
我只想说,谢谢你,这是我见过的最快的生成数据的方法,不用做太多的工作。我真的在几秒钟内做了一个2GB的文件,我需要32字节的十六进制字符串,这做的很好 time xxd -c 32 -l 1024000000 -ps /dev/urandom 32bytehexnewtest1.txt ; real 0m17.484s
Zibri
Zibri
发布于 2015-11-16
0 人赞同

替换代码0】和 xxd 给出了不同编码的结果!

$ echo -n $'\x12\x34' | xxd -p
$ echo -n $'\x12\x34' | hexdump -e '"%x"'

简单解释。大空位对小空位 :D

使用 echo -n $'\x12\x34' | hexdump -e '/1 "%x"' 来获得相同的字节数。
还要注意! hexdump 将剥离前导零。
Håkon A. Hjortland
Håkon A. Hjortland
发布于 2015-11-16
0 人赞同

With od (GNU systems):

$ echo abc | od -A n -v -t x1 | tr -d ' \n'
6162630a

With hexdump (BSD systems):

$ echo abc | hexdump -ve '/1 "%02x"'
6162630a

From 六进制转储、od和hexdump:

"根据你的系统类型,这两个工具中的一个或两个都可以使用--BSD系统废除了hexdump的od,GNU系统则相反。"

4年了(我知道这不算什么),大多数时候我读到关于*nix的帖子时,都会了解到一些非常老的东西,对我来说仍然是全新的。+我想说的是,我从来没有听说过这个东西,它非常有用,甚至在Cygwin上也有。)
Blagovest Buyukliev
Blagovest Buyukliev
发布于 2015-11-16
0 人赞同

也许你可以用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脚本中。

C,为了这个?这是个过度的问题。
好吧,但你可以完全控制格式和行为 :-)
这总是一个选择,但我很确定它以前已经被解决了 :)
jww
@user405725 - 对于一个C语言程序员来说,这似乎是最简单的解决方案。据我所知,所有其他的解决方案都是这样的 not 对一个二进制文件进行十六进制编码。我对这项任务变得如此困难感到困惑。对一个二进制文件进行十六进制编码真的有那么难吗?
令人难以置信,但这很可能是这个问题的最佳答案。
marcinj
marcinj
发布于 2015-11-16
0 人赞同

所有的解决方案似乎都很难记住或太复杂。我发现使用 printf 是最短的一种。

$ printf '%x\n' 256

但正如评论中指出的,这不是作者想要的,所以为了公平起见,下面是完整的答案。

......使用上述方法来输出实际的二进制数据流。

printf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)

它的作用。

  • printf '%x\n' .... - prints a sequence of integers , i.e. printf '%x,' 1 2 3, will print 1,2,3,
  • $(...) - this is a way to get output of some shell command and process it
  • cat /dev/urandom - it outputs random binary data
  • head -c 5 - limits binary data to 5 bytes
  • od -An -vtu1 - octal dump command, converts binary to decimal
  • 作为一个测试案例('a'是61进制,'p'是70进制,...)。

    $ printf '%x\n' $(echo "apple" | head -c 5 | od -An -vtu1)
    

    或者为了测试单个二进制字节,在输入时让我们给出61个十进制('='字符)来产生二进制数据('\\x%x'格式就可以)。上述命令将正确输出3d(十进制61)。

    $printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1)
        
    @МалъСкрылевъ 我已经更新了我的答案,你是对的,我忽略了问题的重点--我可能在寻找在shell中把十进制转换为十六进制的最简单方法,而这个答案在google中显示为第一。
    嘿,我知道这已经很老了,但是对于第二个代码框,你能不能跳过猫,直接做头?替换代码0】或者有什么特殊的原因需要使用cat命令?另外,如果你想在最后用一个新的行来分隔六角,我想出了这个办法 echo $(printf "%x" $(head -c 5 /dev/urandom | od -An -vtu1)) ,尽管我不知道这些的性能成本,主要是我问为什么要把cat命令删掉。我对命令行很陌生,但这些信息都有帮助。
    @cigolon head is better than cat.我经常使用 time 命令来衡量命令的性能。
    这也是我问这个问题的原因。 替换代码0VS printf '%x\n' $(head -c 5 /dev/urandom | od -An -vtu1) 第二条命令中没有猫管,总体上要快一点。
    Kevin Cox
    Kevin Cox
    发布于 2015-11-16
    0 人赞同

    如果你需要一个大的流(没有换行),你可以使用 tr xxd (Vim的一部分)进行逐个字节的转换。

    head -c1024 /dev/urandom | xxd -p | tr -d $'\n'
    

    Or you can use hexdump (POSIX) for word-by-word conversion.

    head -c1024 /dev/urandom | hexdump '-e"%x"'
    

    请注意,区别在于字节数。

    echo abc | hexdump -e '/1 "%02x"' 来获得网络秩序,用0来获得 0x0a
    user405725
    user405725
    发布于 2015-11-16
    0 人赞同

    dd + hexdump 也会起作用。

    dd bs=1 count=1 if=/dev/urandom 2>/dev/null  | hexdump -e '"%x"'
        
    谢谢,我是这样开始的,但不能让hexdump做我想做的事。我很确定它有我需要的选项,但在man page中找不到这个选项
    With this solution (hexdump -e '"%x"'): '\n' -> 'a' (missing leading '0'), 'abcde' -> '6463626165' (incorrect byte order). This could be very bad in non-random-data applications!
    revl
    revl
    发布于 2015-11-16
    0 人赞同

    如果你的目标是一个以上的平台,有时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
    

    请注意,这样做更多的是使用slurp,它使Perl将整个输入读入内存,当输入量很大时,这可能是不理想的。

    user2350426
    user2350426
    发布于 2015-11-16
    0 人赞同

    这三个命令将打印出相同的内容(0102030405060708090a0b0c)。

    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})")"