為什么說Java中的隨機數都是偽隨機數?


什么是偽隨機數?
   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()會相對來說比較靈活一些。

  

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM