2011-06-09 213 views
34

觉得有点愚蠢的问这个(听起来很基础),但在其他地方找不到答案。我想将二进制数据转换为十六进制,就是说,没有花哨的格式和所有。 hexdump看起来太聪明了,它“为我过度”。我想从/ dev/random中取出x个字节,并以十六进制形式传递它们。在shell脚本中将二进制数据转换为十六进制数据?

最好,我想只使用标准的Linux工具,所以,我并不需要每一台机器上安装它(有很多)

+0

我不得不使用/ dev/urandom,/ dev/random只是冻结 – 2015-04-11 22:18:17

+2

@AquariusPower随机块,当它没有足够的随机数据,而urandom没有(IIRC循环它有什么) – davka 2015-05-20 07:10:54

回答

50

也许使用xxd

% xxd -l 16 -p /dev/random 
193f6c54814f0576bc27d51ab39081dc 
+5

xxd是vim的一部分,所以它可能并不总是被安装。 – 2012-07-24 22:47:00

+1

请注意,您可以使用'-c'来更改每行的字节数。不幸的是,你只能将它设置为256,之后你需要有一些换行符。 – 2013-11-12 18:27:34

8

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

+3

C,对吗?这太过分了。 – 2011-06-09 12:33:16

+1

好吧,但你必须在格式和:-) – 2011-06-09 12:34:30

+0

的行为总是一种选择的完全控制,但我相当肯定它之前:) – davka 2011-06-09 13:26:32

3

DD + hexdump都还将努力:

dd bs=1 count=1 if=/dev/urandom 2>/dev/null | hexdump -e '"%x"' 
+0

谢谢,我以这种方式开始,但不能让hexdump做我想做的事。我很确定它有我需要的选项,但在手册页 – davka 2011-06-09 13:24:22

+2

中找不到这个解决方案(hexdump -e'“%x”'):'\ n' - >'a' '0'),'abcde' - >'6463626165'(不正确的字节顺序)。这在非随机数据应用中可能非常糟糕! – 2012-07-24 22:43:40

19

随着OD(GNU系统):

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

随着hexdump都(BSD系统):

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

http://en.wikipedia.org/wiki/Hex_dump#od_and_hexdump
“视您的系统类型,其中之一或两者这两个实用程序将可用 - BSD系统不赞成使用hexdump,GNU系统则相反。“

+1

4年之后(我知道的并不多),大多数时候我读了一篇关于* nix的文章,我了解了一些非常古老而且对我来说全新的东西。对于od来说+1,从来没有听说过它,即使在Cygwin上也是非常有用的。 ;-) – 2013-09-07 01:47:43

1

如果你需要一个大流(没有换行符),你可以使用trxxd(vim的一部分)进行逐字节转换。可以使用hexdump(posix)进行逐字转换。

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

请注意,不同之处在于字节顺序。

+2

使用'echo abc | hexdump -e'/ 1“%02x”“来获得网络顺序,0为0x0a。 – 2015-11-15 23:04:47

1

这三个命令将打印相同的(0102030405060708090a0b0c):

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 
5

所有的解决方案似乎是很难记住或太复杂,我发现使用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'格式做的话),上述命令将输出正确地三维(十进制61):

$printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1) 
3d 
+0

哇,那简单! – davka 2017-03-06 10:33:03

+0

@МалъСкрылевъ我已经更新了我的答案,你是对的,我错过了问题的主要观点 - 我可能正在寻找最简单的将shell中的十进制转换为十六进制的方式,并且这个答案在谷歌中首先显示。 – marcinj 2017-08-27 06:27:16

相关问题