Shell随机数及字符串翻转

完美世界运维开发的一道笔试题,大概意思是0到9中随机取6个数,然后翻转输出。之前写过一个随机生成root密码的脚本,无奈时间长了忘记了。这里总结一下shell中随机数的生成方法。

时间戳

  • 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

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注