在密码技术中,随机序列是非常重要的,比如密钥产生、数字签名、身份认证和众多的密码学协议等都要用到随机序列。所以产生高质量的随机数序列对信息的安全性具有十分重要的作用。随机数分为真随机数和伪随机数,计算机通过算法产生的随机数并不上真正意义上的随机数,很容易被破解,只能称为伪随机数。若要产生真正的随机数,必须通过硬件来实现,比如使用离子辐射事件的脉冲检测器、气体放电管和带泄露的电容等,但是为每台计算机配备这样的装置上不可能。下面将两种常见的随机算法:线性同余和RSA算法。
1、线性同余
Ni+1=(A*Ni+B)mod M 其中i=0,1,…,M-1
要求:B,M互为质数;M的所有质因子的积能整除A-1;若M是4的倍数A-1也是;A,B,N0都比M小;A,B是正整数(根据此公式可以递推出随机数,有兴趣的可以推倒一下)
因此,取A=7^5;B=0;M=2^31-1; N0为系统时间;满足B=0,M=2^31-1互为质数;M=2^31-1的所有质因子的积能整除A-1=7^5-1;若M是4的倍数A-1也是;A,B,N0都比M小;A,B是正整数。
实现:
package org.mino.random;
/**
* @author DingJie
* @date 2014-5-1
* @email dingjie_nlp@126.com
*/
public class LineRmainderRandom {
private static long initSeed = System.currentTimeMillis();
/**
* @param args
*/
public static void main(String[] args) {
for (int i = 0; i < 100; i++)
{
getRand ();
}
}
private static void getRand ()
{
initSeed = (initSeed * 16807L) % ((1 << 31) - 1);
System.out.println(initSeed);
}
}
其实java.util.Random类中使用的就是线性同余方法:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
2、RSA伪随机数方法
RSA是依据依旧是一个满足一定条件的数学公式
设A从2~(N-1) C=(A EXP D) mod N满足如下条件:D是素数,N是两个素数(P,Q)之积, (D * E) mod ((P-1) * (Q-1))=1 因为:若 C=(A EXP D)mod N 有:A=(C EXP E) mod N 所以,C与A 一一对应;设N=15,P=5,Q=3则A为2到14的数。现在要产生2到14的伪随机数。取D为3,E为3,
C2=(2EXP3)mod15 = 8,
C3=(3EXP3)mod 15 = 12,
C4 = (4EXP3)mod 15= 4,
C5 = (5EXP3)mod 15= 5,
C6 = (6EXP3)mod 15= 6,
C7 = (7EXP3)mod 15= 13,
C8 = (8EXP3)mod 15= 2,
C9 = (9EXP3)mod 15= 9,
C10 = (10EXP3)mod 15= 10,
C11 = (11EXP3)mod 15= 11,
C12 = (12EXP3)mod 15= 3,
C13 = (13EXP3)mod 15= 7,
C14 = (14EXP3)mod 15= 14