随机数生成的N中方法


方法一、通过时间获得随机数date)


这个也是我们经常用到的可以说时间是唯一的也不会重复的从这个里面获得同一时间的唯一值。适应所有程序里面了。


[root@LAMP ~]# date +%s

1444437959

#获得时间戳当前到1970-01-01 00:00:00 相隔的秒数

#如果用它做随机数相同一秒的数据是一样的。在做循环处理多线程里面基本不能满足要求了。

 

[root@LAMP ~]# date +%N

182571596

#获得当前时间的纳秒数据精确到亿分之一秒。

#这个相当精确了就算在多cpu大量循环里面同一秒里面也很难出现相同结果不过不同时间里面还会有大量重复碰撞

 

[root@LAMP ~]# date +%s%N

1444437980485543945

#这个可以说比较完美了加入了时间戳又加上了纳秒

 

#########################################################################

#########################################################################

方法二、通过内部系统变量($RANDOM)



[root@LAMP ~]# echo $RANDOM

17578

[root@LAMP ~]# 

[root@LAMP ~]# echo $RANDOM

31908

 

#连续2次访问结果不一样这个数据是一个小于或等于5位的整数

可能有疑问了如果超过5位的随机数怎么得到呢


那样可以把它们随机生成多次就可以了。如下

如果要生成一个20位的随机数

[root@LAMP ~]# echo $RANDOM$RANDOM$RANDOM$RANDOM$RANDOM |head -20

18362378120701329232381

[root@LAMP ~]# 

==============================================

#得到1-10的seq数据项

[root@centos1 ~]# cat ran.sh 

#!/bin/sh

for i in {1..10};

do 

    out="$RANDOM";

    echo $i,$out;

done;


[root@centos1 ~]# sh ran.sh  

1,10709

2,8091

3,1061

4,21717

5,1362

6,1515

7,8635

8,8435

9,16233

10,15663

[root@centos1 ~]#


#########################################################################

#########################################################################


方法三、通过系统内部唯一数据生成随机数/dev/random,urandom)


我们知道dev目录下面是linux一些默认设备它给我们感觉就是放的是键盘硬盘光驱等设备的对应文件了。 其实linux有些设备很特殊有特殊用途。前面我们说到的/dev/[udp|tcp]/host/port比较特殊吧。呵呵有扯远了。


/dev/random设备存储着系统当前运行的环境的实时数据。它可以看作是系统某个时候唯一值数据因此可以用作随机数元数据。我们可以通过文件读取方式读得里面数据。/dev/urandom这个设备数据与random里面一样。只是它是非阻塞的随机数发生器读取操作不会产生阻塞。


实例

[root@LAMP ~]# head -1 /dev/urandom

>^Bi]caVfO[~TLp)4Am"jFroh`X_\)}uzB$64_   &0dfLtQtTN:′^K\-Up G>Λ4) f)f^]v?85aqoMMkh1CU{FBo-z.`g^eHi*: 5y6JWLk{nZ61~`,N(r|@

[root@LAMP ~]#

 

#读一行怎么是乱码呢其实它是通过二进制数据保存实时数据的那么我们怎么样把它变成整型数据呢

 

[root@LAMP ~]# cat /dev/urandom |head -1|cksum 

1994079391 697

[root@LAMP ~]# cat /dev/urandom |head -1|cksum  

4290260108 501



[root@LAMP ~]# cat /dev/urandom |head -1|md5sum 

4c70ead6691149b60a5b630515baffef  -

[root@LAMP ~]#

#由于urandom的数据是非常多不能直接通过cat读取这里取前1行其实整个数据都是变化的取多少也一样是唯一的。

#cksum 将读取文件内容生成唯一的表示整型数据只有文件内容不变生成结果就不会变化,与php crc函数

 

[root@LAMP ~]# cat /dev/urandom |head -1|cksum|cut -f1 -d" "

3923336389


#cut 以” “分割然后得到分割的第一个字段数据得到整型数据然后类似一的方法就可以获得到随机数了。 题外话在程序里面我们经常md5得到唯一值然后是字符串的如果想表示成整型方式可以通过crc函数.crc是循环冗余校验相同数据通过运算都会得到一串整型数据。现在这种验证应用很广。详细要了解可以参考crc.



生成随机字母

生成全字符随机的字串

cat /dev/urandom | strings -n C | head -n L


生成数字加字母的随机字串

cat /dev/urandom | sed 's/[^a-zA-Z0-9]//g' | strings -n number | head -number L


-n number 仅输出长度大于number的字符串

L表示要生成多少行字符。


生成全部都是字母

[root@LAMP 03]# cat /dev/urandom | sed 's/[^a-z]//g' | strings -n 10 | head -1 

dweyzakcdeljl

[root@LAMP 03]# cat /dev/urandom | sed 's/[^a-z]//g' | strings -n 20 | head -1  

vxonfaydrwzqzyehctknrlblxqilytm


生成的全部是数字

[root@LAMP 03]# cat /dev/urandom | sed 's/[^0-9]//g' | strings -n 10 | head -1   

2285526581321014

[root@LAMP 03]# 


#########################################################################

#########################################################################

方法四、读取linux 的uuid码


在提到这个之前有个概念就是什么是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码


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

[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid

dff68213-b700-4947-87b1-d9e640334196

[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid

7b57209a-d285-4fd0-88b4-9d3162d2e1bc

[root@centos1 ~]#  cat /proc/sys/kernel/random/uuid 

f363b778-b5f0-491d-92ff-fd0d58fadaa3

[root@centos1 ~]# 

[root@centos1 ~]#  cat /proc/sys/kernel/random/uuid |cksum 

1121596108 37

[root@centos1 ~]#  cat /proc/sys/kernel/random/uuid |md5sum 

7d3cffeb4136516d478bbe20df03ccc2  -

[root@centos1 ~]#

#连续2次读取得到的uuid是不同的

 

[chengmo@centos5 ~/shell]$ cat /proc/sys/kernel/random/uuid| cksum | cut -f1 -d" "

2141807556

#同上方法得到随机整数

 



范例1.随便输入一个人的名字就好产生一个4位的随机数并且随机数的第一位不能为0.如果是0重新生成一个四位随机数。

[root@LAMP 03]# cat ran.sh 

#!/bin/sh

a=$1

while true

do

num=`echo $RANDOM|cut -c 1-4`

b=`echo $num|cut -c 1`

if [ $b -gt 0 ]

 then

 echo "$a=========>$num"

 exit 0

fi

done


[root@LAMP 03]#

=======================

[root@LAMP 03]# sh ran.sh xia

xia=========>3121

[root@LAMP 03]# sh ran.sh xia0

xia0=========>7314

[root@LAMP 03]# sh ran.sh xia3

xia3=========>1818