完美世界运维开发的一道笔试题,大概意思是0到9中随机取6个数,然后翻转输出。之前写过一个随机生成root密码的脚本,无奈时间长了忘记了。这里总结一下shell中随机数的生成方法。
Contents
时间戳
date +%s
获得时间戳,当前到:1970-01-01 00:00:00 相隔的秒数。如果用它做随机数,相同一秒的数据是一样的。在做循环处理,多线程里面基本不能满足要求了。date +%N
获得当前时间的纳秒数据,精确到亿分之一秒。这个相当精确了,就算在多cpu,大量循环里面,同一秒里面,也很难出现相同结果,不过不同时间里面还会有大量重复碰撞date +%s%N
这个可以说比较完美了,加入了时间戳,又加上了纳秒
内部系统变量($RANDOM)
[root@HADOOP-215 shell]# echo $RANDOM
20512
[root@HADOOP-215 shell]# echo $RANDOM
28063
[root@HADOOP-215 shell]# echo $RANDOM
1004
连续2次访问,结果不一样,这个数据是一个小于或等于5位的整数
系统内部唯一数据生成随机数(/dev/random,urandom)
[root@HADOOP-215 shell]# head -1 /dev/urandom
tKe\b⺭!t刘.£ v 䀎@N
[root@HADOOP-215 shell]# head -1 /dev/urandom | cksum
212940846 383
#由于urandom的数据是非常多,不能直接通过cat读取,这里取前200行,其实整个数据都是变化的,取多少也一样是唯一的。
#cksum 将读取文件内容,生成唯一的表示整型数据,只有文件内容不变,生成结果就不会变化,与php crc函数
[root@HADOOP-215 shell]# head -1 /dev/urandom | cksum |cut -f1 -d" "
2486556132
读取linux的uuid码
[root@HADOOP-215 shell]# cat /proc/sys/kernel/random/uuid
696986e1-9339-4d71-b307-381489f0f537
[root@HADOOP-215 shell]# cat /proc/sys/kernel/random/uuid
1cb47b68-4c60-4016-ada0-8ddc0fcdd9d9
#连续2次读取,得到的uuid是不同的
[root@HADOOP-215 shell]# cat /proc/sys/kernel/random/uuid |cksum
454615131 37
[root@HADOOP-215 shell]# cat /proc/sys/kernel/random/uuid |cksum |cut -f1 -d" "
852465649
字符串翻转
[root@localhost vodcdnsrc]# echo 'abcdefg'|awk '{for(i=1;i<=length;i++){line=substr($0,i,1)line}}END{print line}'
gfedcba
[root@localhost vodcdnsrc]# echo abc|sed 's/\(.\)\(.\)\(.\)/\3\2\1/'
cba
[root@localhost vodcdnsrc]# echo 'abcdef'|rev
fedcba
代码实现
#!/bin/bash
#-----------------------------------------------------------
# Usage: 随机数
# $Id: random.sh i@annhe.net 2015-07-27 02:21:14 $
#-----------------------------------------------------------
function TimestampRand()
{
range=$1
timestamp=`date +%s%N`
let res=$timestamp%$range
echo $res
}
function RandomRand()
{
range=$1
let res=$RANDOM%$range
echo $res
}
function UrandomRand()
{
range=$1
rand=`head -200 /dev/urandom | cksum | cut -f1 -d" "`
let res=$rand%$range
echo $res
}
function UuidRand()
{
range=$1
rand=`cat /proc/sys/kernel/random/uuid| cksum | cut -f1 -
d" "` let res=$rand%$range
echo $res
}
echo "时间戳: `TimestampRand 10`"
echo "\$RANDOM: `RandomRand 10`"
echo "urandom: `UrandomRand 10`"
echo "uuid: `UuidRand 10`"
str=""
for i in `seq 1 6`;do
str="$str`RandomRand 9`"
done
echo $str
echo "翻转:"
echo $str | rev
echo $str | awk '{for(i=1;i<=length;i++){line=substr($0,i,1)line}
}END{print line}'
运行结果
[root@HADOOP-215 shell]# ./random.sh
时间戳: 1
$RANDOM: 0
urandom: 3
uuid: 7
708654
翻转:
456807
456807
参考资料
1. [shell下三种反转字符串的方法]. http://blog.sina.com.cn/s/blog_71555b3b0100x8df.html
2. [linux shell实现随机数多种方法(date,random,uuid)] . http://www.cnblogs.com/chengmo/archive/2010/10/23/1858879.html
发表回复