改进的办法1:互调 date +%N%s (仍然不行):
既然第一位不能为0,那么从纳秒的第2位、第3位.... 截取不行吗,答案也是不可以的,因为纳秒的每一位都有可能是0,毕竟纳秒是9位数(毫秒3位数、微秒6位数、纳秒9位数)纳秒本身就在秒数之后,所以纳秒的9位数的每一位都可以为0 另外,纳秒在高位,秒数在低位,截取大数值可能导致高位不相同,但低位数值相同的情况,原因是秒数的值变化非常慢。结论,互换的办法是行不通的,还可能导致新的问题,因此,老老实实的用 date +%s%N 格式吧
改进的方法2:直接用 date +%s%N 的19位数(可行)
不要截取 date +%s%N | cut -c1-17 ,充分利用纳秒的快速变化后再取余
3. 使用 /dev/random 和 /dev/urandom 随机文件(CentOS、Ubuntu、MacOS 都支持,推荐)
/dev/random 是阻塞的随机数发生器,读取有时需要等待。存储着系统当前运行环境的实时数据,如 CPU、内存、电压、物理信号等
/dev/urandom 是非阻塞随机数发生器,读取操作不会产生阻塞。
说明:
/dev/random 和 /dev/urandom 存储的都是乱码,实际上它们是通过二进制数据保存实时数据的
打开 /dev/random 和 /dev/urandom 文件,推荐用 head,不推荐 cat 命令,因为文件非常大且是乱码,只需要获取前几行文件内容就变了
用到了 cksum 命令,其读取文件内容,生成唯一的整型数据,只有文件内容没变,生成结果就不会变化,与php crc函数类似,一般校验文件是否篡改
其生成随机数的原理是:截取文件的一部分内容,做内容的计算,取第一个数值
# head -20 /dev/urandom | cksum 3535024891 50260 # head -20 /dev/urandom | cksum | cut -f1 -d " " 1713554848
示例:使用/dev/urandom生成 40,000,000~50,000,000 之间的随机数,使用 /dev/urandom 避免阻塞。
#!/bin/bash
# mimvp.com 2016.05.10
## Linux 随机文件
function mimvp_randnum_file() {
min=$1
max=$2
mid=$(($max-$min+1))
num=$(head -n 20 /dev/urandom | cksum | cut -f1 -d ' ')
# num=$(head -n 20 /dev/urandom | cksum | cut -d ' ' -f1) # ok
# num=$(head -n 20 /dev/urandom | cksum | awk '{print $1}') # ok
# num=$(head -n 20 /dev/urandom | cksum | awk -F " " '{print $1}') # ok
randnum=$(($num%$mid+$min))
echo $randnum
}
function print_randnum_file() {
for i in {1..10};
do
randnum=$(mimvp_randnum_file 40000000 50000000)
echo -e "$i t $randnum"
done
}
print_randnum_file
运行结果:
# sh mimvp_shell_rand.sh
1 48894638
2 43078483
3 41678948
4 48987680
5 46095205
6 49650777










