我在while循环中用bash编写了一个脚本。代码:
number=0
while [ 1500 -gt $number ]
do
var="abcdefghijklmnopqrstuvxyz"
letter1="${var:$(( RANDOM % ${#var} )):1}"
letter2="${var:$(( RANDOM % ${#var} )):1}"
a=$RANDOM
b=$RANDOM
c=$(( $a * $b))
echo "$letter1$letter2 $c" >> a.txt
number=$(( 1 + $number ))
done
但是现在我看到重复的数字:
Result:
ab 15474
at 15474
yh 15474
gd 15474
re 18696
jg 18696
数字重复。
我猜想$RANDOM
的变化是不变的,我的脚本再次启动while
循环的速度比$RANDOM
的变化快。
您能帮我另一种随机方法吗?
答案 0 :(得分:3)
我已经尝试过您的脚本,并且对我来说效果很好。
bash中有许多generate random number的方式。一种是使用@Service
public class RecordsTrackerService {
private RestTemplate restTemplate;
@Autowired
public RecordsTrackerService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public void updateRecords() {
Object obj = restTemplate.getForObject("sample_url", Object.class);
}
}
特殊设备文件。 /dev/random
使用从设备驱动程序和其他来源收集的噪声来生成随机数据。 od(八进制转储)命令可以提取多个字节并显示其十进制等效项。
/dev/random
在这里od -A n -t d -N 1 /dev/urandom
指定输出格式应为十进制符号; -t d
说要从/ dev / urandom中读取一个字节。
另一种方法是使用-N 1
命令:
jot
这里我们生成10个介于1和1000之间的数字。jot -r 10 1 1000
指定生成随机数。
答案 1 :(得分:1)
您可以将tr
与/dev/urandom
一起使用:
tr -dc 'a-z' </dev/urandom | head -c 2; echo
使用-c
函数的head
选项设置所需的字符数。
要生成随机数字,请在tr
命令中使用另一组数字:
tr -dc '0-9' </dev/urandom | head -c 4; echo
答案 2 :(得分:0)
@ j23提供了一个非常合理的操作答案。通过对观察到的行为的可能解释,您打印的数字不是单个$RANDOM
值,而是两个此类值的乘积。伪随机数生成器(PRNG)的成对连续输出不一定像您想要的那样独立。例如,Matlab randn
在2006年遇到了关联问题(arXiv:math / 0603058)。
答案 3 :(得分:0)
像这样吗?
#!/bin/bash
export LC_ALL=C
for((i=0; i<1500; ++i)); do
IFS='' read -n 4 -d '' bytes
# https://stackoverflow.com/questions/28476611/ord-and-chr-a-file-in-bash
printf -v a %u "'${bytes:2:1}"
a=$((a%255))
printf -v b %u "'${bytes:3:1}"
b=$((b%255))
printf "%s %s\n" "$(
tr '\000-\011\013-\140\173-\377' 'a-za-za-za-za-za-za-za-za-z' <<<"${bytes:0:2}"
)" $((${a#-}*${b#-}))
done</dev/urandom
当字符代码在0x80以上时,%u
转换会奇怪地创建很大的数字,而其模数255会生成一个负数,因此我不得不采取一些非显而易见的解决方法来解决该问题。也许您可以想出一种比较简单的方法来将两个字节解压缩为一个无符号的15位数字。
这是第二行中的更新,其结果范围为200000-1000000。它需要两个额外的随机字节,然后对结果进行取模和加法运算,以使其达到正确的范围。这是Bash内置算法无法实现的,因此我改用bc
。
#!/bin/bash
export LC_ALL=C
for((i=0; i<1500; ++i)); do
IFS='' read -n 6 -d '' bytes
# https://stackoverflow.com/questions/28476611/ord-and-chr-a-file-in-bash
printf -v a %u "'${bytes:2:1}"
a=$((a%255))
printf -v b %u "'${bytes:3:1}"
b=$((b%255))
printf -v c %u "'${bytes:4:1}"
c=$((c%255))
printf -v d %u "'${bytes:5:1}"
d=$((d%255))
printf "%s %s\n" "$(
tr '\000-\011\013-\140\173-\377' 'a-za-za-za-za-za-za-za-za-z' <<<"${bytes:0:2}"
)" $(bc <<<"((${a#-}*${b#-}*${c#-}*${d#-})%800000)+200000")
done</dev/urandom
这变得非常复杂。如果Bash对您不是必需的,请尝试使用此Python 3脚本。
from random import choice, randrange
from string import ascii_lowercase
for r in range(1500):
print('{0}{1} {2}'.format(
choice(ascii_lowercase),
choice(ascii_lowercase),
200000+randrange(999999800000)))