Shell脚本实现随机数的几种方法介绍(date、random、uuid)

1. 通过时间获得随机数(date)

时间是唯一的,也不会重复,从这个里面获得同一时间的唯一值。

[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$date +%s
1479812238
#获得时间戳,即1970-01-01 00:00:00到当前时间相隔的秒数
#如果用它做随机数,相同一秒的数据是一样的。在做循环处理,多线程里面基本不能满足要求了。
[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$date +%N
265969691
#获得当前时间的纳秒数据,精确到亿分之一秒。
#这个相当精确了,就算在多cpu,大量循环里面,同一秒里面,也很难出现相同结果,不过不同时间里面还会有大量重复碰撞
 
[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$date +%s%N
1479812394056850320
#这个比较完美了,加入了时间戳,又加上了纳秒。

#!/bin/sh

#写个随机函数,调用方法random min max 
#在min 与 max直接获得随机整数

#获得随机数返回值,shell函数里算出随机数后,更新该值
function random()
{
    min=$1;
    max=$2-$1;
    num=$(date +%s+%N);
    ((retnum=num%max+min));
    #进行求余数运算即可
    echo $retnum;
    #这里通过echo 打印出来值,然后获得函数的,就可以获得值
    #还有一种返回,定义全价变量,然后函数改下内容,外面读取
}
 
#得到1-5的seq(sequence)数据项
for i in {1..5};
do
    out=$(random 1 500);
    echo $i,"1-500",$out;
done;

运行结果:

[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$sh a.sh
1,1-500,9
2,1-500,14
3,1-500,61
4,1-500,206
5,1-500,112

一个循环里面,得到值各不相同。 这个是我们常用方法,适应各种语言,是一个通用算法,就算服务器不提供,某时刻相同唯一数据标记,我们也可以通过这种方法,做自己的伪随机数。

2. 通过内部系统变量$RANDOM

linux已经提供有个系统环境变量了,直接就是随机数。

[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$echo $RANDOM
23507

[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$echo $RANDOM
31983
	 
#连续2次访问,结果不一样,这个数据是一个小于或等于5位的整数,取值范围:0~32767
rand={$random} % 60; //通过位拼接操作{}产生0—59范围的随机数
rand=$random % 60; //产生一个在 -59—59范围的随机数
3. 通过系统内部唯一数据生成随机数/dev/random,urandom

dev目录下面,是linux一些默认设备,它给我们感觉就是放的是键盘,硬盘,光驱等设备的对应文件了。 其实linux有些设备很特殊,有特殊用途。前面我们说到的:/dev/[udp|tcp]/host/port比较特殊吧。 /dev/random设备,存储着系统当前运行的环境的实时数据。它可以看作是系统某个时候,唯一值数据,因此可以用作随机数元数据。我们可以通过文件读取方式,读得里面数据。/dev/urandom这个设备数据与random里面一样。只是它是非阻塞的随机数发生器,读取操作不会产生阻塞。 实例:

[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$head -1 /dev/urandom  
hj:c`8%
        ^793F4L\BE;[?Mzf7lq!څNnf`G,:S
                                                 l$e-Oe yG_-!\c;
 
#读一行是乱码,其实它是通过二进制数据保存实时数据的。 
 
[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$head -1 /dev/urandom|cksum
1640711962 89
#由于urandom的数据是非常多,不能直接通过cat读取,这里取第1行,其实整个数据都是变化的,取多少也一样是唯一的。
#cksum 将读取文件内容,生成唯一的表示整型数据,只要文件内容不变,生成结果就不会变化,与php crc函数
 
[xiaowan@xiaowandeMacBook-Pro  /Users/xiaowan]
$head -1 /dev/urandom|cksum|cut -f1 -d" "
3769495405
#cut 以" "分割,然后得到分割的第一个字段数据,得到整型数据,然后,类似一的方法就可以获得到随机数了。 题外话:在程序里面,我们经常md5得到唯一值,然后是字符串的,如果想表示成整型方式,可以通过crc函数.crc是循环冗余校验,相同数据通过运算,都会得到一串整型数据。
4. 读取linux 的uuid码

UUID码全称是通用唯一识别码 (Universally Unique Identifier, UUID),它 是一个软件建构的标准,亦为自由软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。

UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。它会让网络任何一台计算机所生成的uuid码,都是互联网整个服务器网络中唯一的。它的原信息会加入硬件,时间,机器当前运行信息等等。

UUID格式是:包含32个16进位数字,以“-”连接号分为五段,形式为8-4-4-4-12的32个字符。范例;550e8400-e29b-41d4-a716-446655440000 ,所以:UUID理论上的总数为216 x 8=2128,约等于3.4 x 1038。 也就是说若每奈秒产生1兆个UUID,要花100亿年才会将所有UUID用完。

其实,大家做数据库设计时候,肯定听说过,guid(全局唯一标识符)码,它其实是与uuid类似,由微软支持。 这里编码,基本有操作系统内核产生。在windows里面,无论数据库,还是其它软件,很容易得到这个uuid编码。

linux的uuid码也是有内核提供的,在/proc/sys/kernel/random/uuid这个文件内。其实,random目录,里面还有很多其它文件,都与生成uuid有关系的。

[root@iZbp1bjvditkx9yo0f0traZ  /root]
#cat /proc/sys/kernel/random/uuid
78c2efc4-6ea2-4a63-b519-5a2efdb5ba6d

[root@iZbp1bjvditkx9yo0f0traZ  /root]
#cat /proc/sys/kernel/random/uuid
7af38e39-f1d0-42a7-a19c-541a824b4718
#连续2次读取,得到的uuid是不同的
 
[root@iZbp1bjvditkx9yo0f0traZ  /root]
#cat /proc/sys/kernel/random/uuid|cksum|cut -f1 -d" "
2208639308
#同上方法得到随机整数
5. 生成随机字符串
#使用date 生成随机字符串  
[root@iZbp1bjvditkx9yo0f0traZ  /root]
#date +%s%N | md5sum | head -c 10
62c082c3fa
  
#使用 /dev/urandom 生成随机字符串  
[root@iZbp1bjvditkx9yo0f0traZ  /root]
#cat /dev/urandom | head -n 10 | md5sum | head -c 10
a0ca2ebdc1

这是linux下面,几种常见活动随机数整数方法,除了第一个是不同外,后4个产生随机码的伪数据来源,都与/dev/random设备有关系。只是它们各自呈现不同而已。

评论

评论正在提交中...请稍后
评论提交成功...
  1. #1

    松松软文发布 (2016-11-23 08:37:44) 沙发
    代码的就是看不懂

  2. #2

    Suvan (2016-11-23 15:34:08) 板凳
    不用看懂,复制就能用。?

  3. #3

    夏日博客 (2016-11-23 15:37:34) 地板
    还未用过 Shell脚本 呢。

  4. #4

    Suvan (2016-11-23 17:14:18)
    你这话说的我丝毫不敢相信~~?