咱們先來看一個實例java
public class SecureTest { public static void main(String[] args) { Random random1 = new Random(23468); for (int i = 0;i < 10;i++) { System.out.println(random1.nextInt(1000)); } System.out.println(""); Random random2 = new Random(23468); for (int i = 0;i < 10;i++) { System.out.println(random2.nextInt(1000)); } } }
運行結果linux
234
344
737
314
431
423
823
503
703
654app
234
344
737
314
431
423
823
503
703
654dom
通過比對,兩次隨機出來是否是很神奇,並且不管你隨機多少次,結果都同樣。這裏就有一個種子值的問題。ide
若是不寫種子值,其實Random會有一個默認的種子值,這個值就是 System.currentTimeMillis() ,因此咱們在代碼開發中,你通常不要使用System.currentTimeMillis()來做爲token之類的發送給用戶,不然將有可能會做爲攻擊憑證來獲取你的隨機數,那麼你的隨機數將無任何意義。spa
由於Random的種子可預測,咱們能夠使用SecureRandom來代替Random,SecureRandom是繼承於Random的一個類。雖然相同的種子產生的隨機數也相同,但SecureRandom的默認種子將再也不是System.currentTimeMillis(),而是操做系統裏面的一些隨機事件。操作系統
public class SecureTest { public static void main(String[] args) { SecureRandom random1 = new SecureRandom(); byte[] seeds = SecureRandom.getSeed(64); random1.setSeed(seeds); for (int i = 0;i < 10;i++) { System.out.println(random1.nextInt(1000)); } System.out.println(""); SecureRandom random2 = new SecureRandom(); random2.setSeed(seeds); for (int i = 0;i < 10;i++) { System.out.println(random2.nextInt(1000)); } } }
運行結果blog
931
443
917
223
566
858
494
706
539
360繼承
931
443
917
223
566
858
494
706
539
360token
若是不手工設置種子值,就是取/dev/urandom裏面的值做爲種子值。