Bash 函数,该函数从/dev/random生成随机字符

Bash 函数,该函数从/dev/random生成随机字符,bash,random,Bash,Random,在我的.bashrc文件中,我添加了一行psswd(){LC_ALL=C tr-dc'a-zA-Z0-9-!“@/#$%^&*()头-C“$1”;echo;}这样,当我在终端中键入psswd n时,它将返回一个由n个随机字符组成的字符串。我希望实现同样的效果,但使用/dev/random而不是/dev/urandom。但是,当我将/urandom替换为/random时,调用psswd不起任何作用(1小时后甚至无法输出一个随机字符)我不知道为什么,我知道这不是没有足够的熵的问题。原因是命令od-A

在我的.bashrc文件中,我添加了一行
psswd(){LC_ALL=C tr-dc'a-zA-Z0-9-!“@/#$%^&*()头-C“$1”;echo;}
这样,当我在终端中键入
psswd n
时,它将返回一个由n个随机字符组成的字符串。我希望实现同样的效果,但使用/dev/random而不是/dev/urandom。但是,当我将/urandom替换为/random时,调用psswd不起任何作用(1小时后甚至无法输出一个随机字符)我不知道为什么,我知道这不是没有足够的熵的问题。原因是命令
od-An-N1-I/dev/random
返回一个随机数

请注意,如果我在重新启动后键入最后一个命令,它几乎会立即返回一个随机数。但是,如果我使用/random调用了对psswd n的调用,那么该命令将在大约15秒后返回一个随机数。因此,对/random的调用似乎对/dev/random有一些影响,即使在我调用funct时它不会产生任何输出离子psswd

总的来说,我想知道如何创建一个使用/dev/random生成n个字符的随机字符串的函数

…当我用
/random
替换
/urandom
时,调用psswd没有任何作用

这种情况经常发生

在类Unix操作系统中,
/dev/random
是一个特殊文件,用作阻塞伪随机数生成器…. 与
/dev/random
相对应的是
/dev/uradom
(“无限”/非阻塞随机源[重点添加]

“阻塞”意味着当它认为它已经耗尽了熵时,它停止生成数字。例如,在我的系统上,管道中的第一个命令生成以下命令:

$ LC_ALL=C tr -dc 'a-zA-Z0-9-!"@/#$%^&*()_+~' < /dev/random  
~Sk(+!h

这是因为当
libc
不是终端时,它将缓冲
tr
的输出。在GNU/Linux上,它是4096字节。这意味着
tr
必须在
head
看到前几个字节之前产生4096字节的输出,即使它只要求例如8

由于256个值中只保留了78个,因此在获得密码之前,
/dev/random
必须平均生成
4096*256/78
=13443字节的随机输出

/dev/random
在我的系统上,从一个空池开始,需要26秒才能生成20个字节。这意味着这些字节将需要
13443*26/20
=17475秒,或近5小时才能生成密码

此时,它将打印密码,但需要另一个缓冲区才能使
tr
实现
head
不再需要的功能,因此需要另外5个小时才能退出命令

如果禁用缓冲,则只需生成
(8+1)*256/78
=29个字节,只需约38秒。在GNU/Linux上,可以使用
stdbuf-o0

$ time { LC_ALL=C stdbuf -o0 tr -dc 'a-zA-Z0-9-!"@/#$%^&*()_+~' < /dev/random | head -c 8; echo; }
9D^MKbT)

real    0m36.172s
user    0m0.000s
sys     0m0.010s
$time{LC_ALL=C stdbuf-o0 tr-dc'a-zA-Z0-9-!”@/$%^&*()头+~'
请问您为什么要使用
/dev/random
?(另请参见)我可以问一下,最初要求您解决的问题是什么吗?为什么
/dev/random
对于原始问题的解决变得如此重要?你没有说明你打算解决什么问题。@melpomene:基本上是为了好玩。它正在做一些我已经可以用urandom做的事情,用random。瑞恩:我没有被要求解决任何问题。我只想在bash中创建一个函数,使用/dev/random生成一个由n个随机字符组成的字符串?基本上,这就是我尝试这种方法的原因,请注意倒数第二个命令与我在.bashrc文件中尝试的命令非常相似。但是它使用/dev/urandom,而不是/dev/random。命令LC_ALL=C tr-dc'a-zA-Z0-9-!“@/#$%^&*()+~'/dev/random可能必须在
tr
的输出有一个字符之前产生几个字符。此外,
头在产生任何输出之前正在等待
$1`字符或SIGPIPE。因此,一个字符
/dev/random
中的er只有在您要求输入1个字符的密码时才会生成输出,而
/dev/random
生成的字符恰好与
tr
命令中的列表匹配。我明白了。另一个问题:为什么od会得到输出?od-an-N10-tc/dev/random会向我返回数字和特殊字符,几乎立刻。
$ time { LC_ALL=C stdbuf -o0 tr -dc 'a-zA-Z0-9-!"@/#$%^&*()_+~' < /dev/random | head -c 8; echo; }
9D^MKbT)

real    0m36.172s
user    0m0.000s
sys     0m0.010s