什么是偽隨機數?
1.偽隨機數是看似隨機實質是固定的周期性序列,也就是有規則的隨機。
2.只要這個隨機數是由確定算法生成的,那就是偽隨機,只能通過不斷算法優化,使你的隨機數更接近隨機。
(隨機這個屬性和算法本身就是矛盾的)
3.通過真實隨機事件取得的隨機數才是真隨機數。
Java隨機數產生原理:
Java的隨機數產生是通過線性同余公式產生的,也就是說通過一個復雜的算法生成的。
偽隨機數的不安全性:
Java自帶的隨機數函數是很容易被黑客破解的,因為黑客可以通過獲取一定長度的隨機數序列來推出你的seed,然后就可以預測下一個隨機數。
不用種子的不隨機性會增大的原因:
java.Math.Random()實際是在內部調用java.util.Random()的,使用一個和當前系統時間有關的數字作為種子數。兩個隨機數就很可能相同。
double a = Math.random();
double b = Math.random();
Random r1 = new Random();
r1.nextInt(10);
Random r2 = new Random();
r2.nextInt(10);
Java中產生隨機數的方法有兩種:
第一種:Math.random()
第二種:new Random()
一、java.lang.Math.Random:
調用這個Math.Random()函數能夠返回帶正號的double值,取值范圍是[0.0,1.0),在該范圍內(近似)均勻分布。因為返回值是double類型的,小數點后面可以保留15位小數,所以產生相同的可能性非常小,在這一定程度上是隨機數。
二、java.util.Random:
Random r1 = new Random();
Random r2 = new Random();
Random r3 = new Random(10);
Random r4 = new Random(10);
下面Random()的兩種構造方法:
Random():使用一個和當前系統時間對應的相對時間有關的數字作為種子數。
Random(long seed):直接傳入一個種子數。
種子的作用是什么?
種子就是產生隨機數的第一次使用值,機制是通過一個函數,將這個種子的值轉化為隨機數空間中的某一個點上,並且產生的隨機數均勻的散布在空間中。以后產生的隨機數都與前一個隨機數有關。
舉例:
Random r =new Random(100);
System.out.println(r.nextInt(20));
種子數只是隨機算法的起源數字,和生成的隨機數字的區間沒有任何關系。
初始化時100並沒有起直接作用(注意:不是沒有起作用),r.nextInt(20)中的20是隨機數的上限,產生的隨機數為0-20的整數,不包括20。
舉例:
Random r1 = new Random(); Random r2 = new Random(); //無參構造使用的是參數作為種子數
Random r3 = new Random(100); Random r4 = new Random(100); //產生隨機數調用nextXXX()方法
System.out.println(r1.nextInt(10)); System.out.println(r1.nextInt(10)); System.out.println(r2.nextInt(10)); System.out.println(r2.nextInt(10)); System.out.println("-----------------"); System.out.println(r3.nextInt(10)); System.out.println(r3.nextInt(10)); System.out.println(r4.nextInt(10)); System.out.println(r4.nextInt(10));
結果:
5
1
4
0
-----------------
5
0
5
0
總結:
1.同一個種子,生成N個隨機數,當你設定種子的時候,這N個隨機數是什么已經確定。相同次數生成的隨機數字是完全相同的。
2.如果用相同的種子創建兩個 Random 實例,如上面的r3,r4,則對每個實例進行相同的方法調用序列,它們將生成並返回相同的數字序列。
3.Java的隨機數都是通過算法實現的,Math.random()本質上屬於Random()類。
4.使用java.util.Random()會相對來說比較靈活一些。