我與commons-lang3系列——RandomUtils

編程過程中經常會有產生隨機數的需求,java.util.Random是我經常使用的,舉例如下:

// 固定seed
Random t = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t.nextInt(100) +" ");
}
// 以系統時鐘作爲seed
Random timeRandom = new Random();
for (int i = 0; i < 5; i++) {
    System.out.println(timeRandom.nextInt(100) +" ");
}

僞隨機數和真隨機數

先了解一下這2個概念:

  • 真隨機數,通過物理實驗得出,比如擲錢幣、骰子、轉輪、使用電子元件的噪音、核裂變等
  • 僞隨機數,通過一定算法和種子得出。軟件實現的是僞隨機數

而僞隨機數也分爲強僞隨機數和弱僞隨機數兩類:

  • 強僞隨機數,難以預測的隨機數,例如java.security.SecureRandom
  • 弱僞隨機數,易於預測的隨機數,例如java.util.Random

也就是說我們程序裏用的都是僞隨機數,而弱僞隨機數(比如基於固定seed或者系統時鐘seed)是可預測(重複)的,參考如下代碼,seed固定爲100的Random實例,產生的隨機數序列是一模一樣的,也就是說如果一旦黑客知道了你的seed,完全可以預測程序的下一個隨機數是什麼。

//固定seed
Random t = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t.nextInt(100) +" ");
}
Random t2 = new Random(100);
for (int i = 0; i < 5; i++) {
    System.out.println(t2.nextInt(100) +" ");
}

這個會有什麼危害呢?如果隨機數影響了程序的校驗邏輯,比如用於產生隨機的短信的驗證碼,如果被不法分子獲取了seed,那就可以破解驗證碼的校驗流程了,後果非常嚴重。但是也不是所有的場景都要用強僞隨機數,不是安全場景的隨機數,使用Random就好,如果想了解詳細的細節,請參考文章:http://netsecurity.51cto.com/art/201605/511983.htm

RandomUtils簡介

commons-lang3裏有RandomUtils工具類,它裏面提供裏多個函數可以方便的的產生隨機數,生成int,long,double,boolean,float,bytes幾種類型,能滿足基本的隨機數產生需求,如下圖:

由於是產生隨機數的靜態工具類,類初始化時內部已經創建了java.util.Random實例,其他的靜態工具方法都是基於這個實例產生的隨機數,所以其本質上也是僞隨機數,而且是弱僞隨機數(基於系統時間的seed):

private static final Random RANDOM = new Random();

歡迎關注我的個人的博客www.zhijianliu.cn, 虛心求教,有錯誤還請指正輕拍,謝謝

版權聲明:本文出自志健的原創文章,未經博主允許不得轉載

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章