有人能解释一下为什么这个脚本有时只返回 15 个字节的十六进制字符串表示吗?

for i in {1..10}; do
  API_IV=`openssl rand 16`; API_IV_HEX=`echo -n "$API_IV" | od -vt x1 -w16 | awk '{$1="";print}'`; echo $API_IV_HEX;
done

像这样:
c2 2a 09 0f 9a cd 64 02 28 06 43 f8 13 80 a5 04
fa c4 ac b1 95 23 7c 36 95 2d 5e 0e bf 05 fe f4
38 55 d3 b4 32 bb 61 f4 fd 17 92 67 e2 9b b4 04
6d a7 f8 46 e9 99 bd 89 87 f9 7f 2b 15 5a 17 8a
11 c8 89 f4 8f 66 93 f1 6d b9 2b 64 7e 01 61 68
93 e3 9d 28 95 e1 c8 92 e5 62 d9 bf 20 b3 1c dd
37 64 ef b0 2f da c7 60 1c c8 20 b8 28 9d f9
29 f0 5a e9 cc 36 66 de 02 82 fc 8e 36 bf 5d d1
b2 57 d8 79 21 df 73 1c af 07 e9 80 0a 67 c6 15
ba 77 cb 92 39 42 39 f9 a4 57 c8 c4 be 62 19 54

如果将“openssl rand 16”直接传送到 od 命令,则它可以正常工作,但我需要二进制值。谢谢你的帮助。

最佳答案

echo 与其他各种标准命令一样,将 \x00 视为字符串结束标记。所以在它之后停止显示。

也许您正在寻找 -hexopenssl rand 选项:

sh$ openssl rand 16 -hex
4248bf230fc9dd927ab53f799e2a9708

鉴于该选项在您的系统上可用,您的示例可以重写:
sh$ openssl version
OpenSSL 1.0.1e 11 Feb 2013

sh$ for i in {1..10}; do
    openssl rand 16 -hex | sed -e 's|..|& |g' -e 's| $||'
done
20 cb 6b 7a 85 2d 0b fe 9e c7 d0 4b 91 88 1b bb
5d 74 99 5e 05 c9 7d 9d 37 dd 02 f3 23 bb c5 b7
51 e9 0f dc 58 04 5e 30 e3 6b 9f 63 aa fc 95 05
fc 6b b8 cb 05 82 53 85 78 0e 59 13 3b e7 c1 4b
cf fa fc d9 1a 25 df e0 f8 59 71 a6 2c 64 c5 87
93 1a 29 b4 5a 52 77 bb 3f bb 1d 0a 46 5d c8 b4
0c bb c2 b2 b4 89 d4 37 1c 86 0a 7a 58 b8 64 e2
ee fc a7 ec 6c f8 7f 51 04 43 d6 00 d8 79 65 43
b9 73 9e cc 4b 42 9e 64 9d 5b 21 6a 20 b7 c3 16
06 8a 15 22 6a d5 ae ab 9a d2 9f 60 f1 a9 26 bd

如果您稍后需要从十六进制转换为字节,请使用此 perl one-liner:
echo MY_HEX_STRING |
  perl -ne 's/([0-9a-f]{2})/print chr hex $1/gie' |
  my_tool_reading_binary_input_from_stdin

(来自 https://stackoverflow.com/a/1604770/2363712 )

请注意,我通过管道连接到客户端程序,并且在此处不使用 shell 变量,因为我认为它无法正确处理 \x00

由于 bash 无法正确处理包含 \x00 的二进制字符串,如果您绝对想坚持使用 shell 编程,那么最好的选择是使用中间文件来存储二进制数据。而不是一个变量:

这就是想法。随意适应您的需求:
for i in {1..10}; do
    openssl rand 16 > api_iv_$i # better use `mktemp` here
    API_IV_HEX=`od -vt x1 -w16 < api_iv_$i | awk '{$1="";print}'`
    echo $API_IV_HEX;
done

sh$ bash t.sh
cf 06 ab ab 86 fd ef 22 1a 2c bd 7f 8c 45 27 e5
2a 01 9c 7a fa 15 d3 ea 40 89 8b 26 d5 4f 97 08
55 2e c9 d3 cd 0d 3a 6f 1b a0 fe 38 6d 0e 20 07
fe 60 35 62 17 80 f2 db 64 7a af da 81 ff f7 e0
74 9a 5c 39 0e 1a 6b 89 a3 21 65 01 a3 de c4 1c
c3 11 45 e3 e0 dc 66 a3 e8 fb 5b 8a bd d0 7d 43
a4 ee 80 f8 c8 8b 4e 50 5c dd 21 00 3b d0 bc cf
e2 d5 11 d4 7d 98 08 a7 16 7b 8c 56 44 ba 6d 53
ad 63 65 fd bf 3f 1f 4a a1 c5 d0 58 23 ae d1 47
80 74 f1 d0 b9 00 e5 1d 50 74 53 96 4b ce 59 50

sh$ hexdump -C ./api_iv_10
00000000  80 74 f1 d0 b9 00 e5 1d  50 74 53 96 4b ce 59 50  |.t......PtS.K.YP|
00000010

作为个人意见,如果你真的有很多二进制数据处理,我会建议切换到其他一些更面向数据的语言(Python,...)

关于带有二进制数据的 Bash echo 命令?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24786061/

10-16 11:45