Linux使用/dev/urandom生成随机数

介绍

/dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两个设备的任务,是提供永不为空的随机字节数据流。很多解密程序与安全应用程序(如SSH Keys,SSL Keys等)需要它们提供的随机数据流。

区别

/dev/random依赖于系统中断,在系统的中断数不足时,/dev/random设备会一直封锁,尝试读取的进程就会进入等待状态,直到系统的中断数充分够用, /dev/random设备可以保证数据的随机性。

/dev/urandom不依赖系统的中断,不会造成进程忙等待,但是数据的随机性也不高。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#/bin/sh -
cat /dev/urandom |
od -x |
head -n 1|
cut -d ' ' -f 2- |
awk -v ORS=":"
'{
    for(i=1; i<=NF; i++){
        if(i == NF){
            ORS = "\n";
        }
        print substr($i,1,2) ":" substr($i,3,2);
    }
}'

od -x表示读取一行数据流转换为16进制,cut -d表示数据截取

随机转换为md5(20位):

head /dev/urandom | md5sum | head -c 20

随机纯数字(20位):

head /dev/urandom | tr -dc 0-9 | head -c 20

随机小写字母+数字(20位):

head /dev/urandom | tr -dc a-z0-9 | head -c 20

随机大小写字母+数字(20位):

head /dev/urandom | tr -dc A-Za-z0-9 | head -c 20

go程序中应用

1
2
3
4
5
6
7
8
9
c := "cat /dev/urandom | od -x | tr -d ' ' | head -n 1"
cmd := exec.Command("sh", "-c", c)
out, err := cmd.Output()
log.Printf("out %s, err %v\n", string(out), err)

c = `cat /dev/urandom | od -x | head -n 1| cut -d ' ' -f 2- | awk -v ORS=":" '{ for(i=1; i<=NF; i++){ if(i == NF){ ORS = "\n"; } print substr($i,1,2) ":" substr($i,3,2); } }'`
cmd = exec.Command("sh", "-c", c)
out, err = cmd.Output()
log.Printf("out %s, err %v\n", string(out), err)

c程序中使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
    int fd=0;
    char *buff=NULL;
    unsigned long ulTest = 0;

    fd=open("/dev/urandom",O_RDONLY);

    read(fd,&ulSeed,sizeof(ulTest));
    printf("%ul",ulTest);

    close(fd);
}

其它生成随机数方式

head -c 32 /dev/random | base64

使用/dev/urandom和chksum生成随机数

head /dev/urandom | cksum

使用系统环境变量($RANDOM)生成随机数

echo $RANDOM
echo $RANDOM | md5sum | cut -c 5-11

使用openssl生成随机数

openssl rand -base64 30
openssl rand -hex 10

使用data时间生成随机数

date +%s%N

使用Linux UUID生成随机数

cat /proc/sys/kernel/random/uuid
cat /proc/sys/kernel/random/uuid | cksum | cut -f1 -d ' '

SHA+date+base64,密码长度32

date +%s | sha256sum | base64 | head -c 32 ; echo

使用/dev/urandom并过滤掉那些日常不怎么使用的字符,输出结果的前32个字符

< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32};echo;

类似于之前的/dev/urandom,但它是反向工作的

tr -cd '[:alnum:]' < /dev/urandom | fold -w30 | head -n1

使用string命令,它从一个文件中输出可打印的字符串

strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n'; echo

使用/dev/urandom的一个更简单的版本

< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6

使用非常有用的dd命令

dd if=/dev/urandom bs=1 count=32 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev

可以生成一个只用左手便可以输入的密码

</dev/urandom tr -dc '12345!@#$%qwertQWERTasdfgASDFGzxcvbZXCVB' | head -c8; echo ""

保存为函数randpw生成随机密码

randpw(){ < /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16};echo;}

最简单的

date | md5sum
date | base64
ifconfig | md5sum
ifconfig | base64

参考