在bash中创建具有随机可打印字符串的特定大小的文件

SaA*_*mic 3 string random bash

我想创建一个仅包含bash中可打印字符串的特定大小的文件。

我的第一个想法是使用/dev/urandom

dd if=/dev/urandom of=/tmp/file bs=1M count=100
  100+0 records in
  100+0 records out
  104857600 bytes (105 MB, 100 MiB) copied, 10,3641 s, 10,1 MB/s

file /tmp/file && du -h /tmp/file
  /tmp/file: data
  101M  /tmp/file
Run Code Online (Sandbox Code Playgroud)

这给我留下了一个所需大小的文件,但不仅包含可打印的字符串。

现在,我可以strings用来创建仅包含可打印字符串的文件。

cat /tmp/file | strings > /tmp/file.txt
file /tmp/file.txt && du -h /tmp/file.txt 
  /tmp/file.txt: ASCII text
  7,0M  /tmp/file.txt
Run Code Online (Sandbox Code Playgroud)

这给我留下了一个仅包含可打印字符串但文件大小错误的文件。

TL; DR

如何在bash中创建特定大小的文件,仅包含可打印的字符串?

sor*_*tar 5

正确的方法是使用类似于base64的转换将随机字节转换为字符。那将不会消除任何来源的随机性,只会将其转换为其他形式。
对于大小为1 MB的文件(稍大一点):

dd if=/dev/urandom bs=786438 count=1 | base64 > /tmp/file
Run Code Online (Sandbox Code Playgroud)

生成的文件将包含A–Za–z0–9和范围内的字符+/=

下面是文件变大的原因,以及一个解决方案。

您可以添加一个过滤器,使用tr将其从该列表转换为其他列表(大小相同或更小)。

cat /tmp/file | tr 'A-Za-z0-9+/=' 'a-z0-9A-Z$%'
Run Code Online (Sandbox Code Playgroud)

我离开了=翻译的范围,因为对于均匀的随机分布,最好省略(几乎)始终是的最后一个字符=

尺寸

文件的大小将从/ dev / random中使用的原始大小扩展到4/3。那是因为我们将256个字节的值转换为64个不同的字符。这是通过从字节流中提取6位来编码每个字符来完成的。当已对4个字符进行编码(6 * 4 = 24位)时,仅消耗了三个字节(8 * 3 = 24)。

因此,我们需要一个3的字节数才能得到准确的结果,而4的字节数是必须的,因为我们必须除以该数。
我们无法获得恰好1024字节(1k)或1024 * 1024 = 1,048,576字节(1M)的随机文件,因为两者都不是3的精确倍数。但是我们可以产生一个更大的文件并截断​​它(如果这样的精度为需要):

wanted_size=$((1024*1024))
file_size=$(( ((wanted_size/12)+1)*12 ))
read_size=$((file_size*3/4))

echo "wanted=$wanted_size file=$file_size read=$read_size"

dd if=/dev/urandom bs=$read_size count=1 | base64 > /tmp/file

truncate -s "$wanted_size" /tmp/file 
Run Code Online (Sandbox Code Playgroud)

截断为确切值的最后一步是可选的。

随机性产生。

当您要从urandom中提取大量随机值时,请不要使用random(使用urandom),否则您的应用将被长时间阻止,并且计算机的其余部分将正常运行。

我建议您安装已安装以下软件包:

haveged使用HAVEGE(硬件易变熵收集和扩展)来维护一个1M的随机字节池,该字节池用于填充/ dev / random,只要dev / random中的随机位供应量低于设备的低水位线。

如果可能的话。