例子:
$ decimal=$(( RANDOM << 17 | RANDOM << 2 | RANDOM >> 13 ))
$ echo $decimal
$ printf "%08x" $decimal | xxd -r -p >bytes
结果在bytes
文件中。
是否可以在单个命令中完成,而无需先将其不必要地转换为十六进制?
答案1
您可以使用printf
内置函数发出八进制代码给出的字节。
x=1193046
printf "$(printf "\\%03o" $((x>>24&255)) $((x>>16&255)) $((x>>8&255)) $((x&255)))"
答案2
您可以使用perl
:
$ perl -e 'print pack "I>", shift' $(( RANDOM << 17 | RANDOM << 2 | RANDOM >> 13 ))
答案3
dc
可以采用任意输入基数并以同样任意的输出基数进行输出。您dc
通过首先传递一个值来与之通信(或由空格分隔的值字符串)接下来是处理该值的命令。dc
输入和输出默认都以 10 为基数。
例如,将任意十进制值转换为二进制值(或者至少以 2 为底):
printf 2o%dp "'A" | dc
1000001
这相当于以下命令列表dc
:
将 2 添加到主堆栈顶部
从主堆栈中弹出顶部值并将其值用作
o
输出基数添加 65(在我的区域设置中转换的 A 的 ASCII 十进制值
printf
)到主堆栈的顶部从主堆栈中弹出顶部值并将
p
其值打印到stdout
当前指定为输出基数的基数中
dc
还将打印由其输入基数解释的字节的 ASCII 值:
printf 8i%oP "'A" | dc
A
...和...
printf 2i%sP 1000001 | dc
A
该过程与之前的过程非常相似,除了i
用于指定i
输入基数(而不是之前的o
输出基数)以及P
用于将顶部堆栈值解释为输出上的 ASCII 字符之外。
bc
可以做很多相同的事情,尽管它的语法往往更加冗长。做man dc
更多man bc
。不过,按位移位并不属于这两个程序的功能。尽管如此,正如您所展示的,任何 POSIX shell 都可以相当轻松地通过算术扩展来处理这一问题。