閱讀136 返回首頁    go 技術社區[雲棲]


Java中的隨機數生成器:Random,ThreadLocalRandom,SecureRandom

文中的

Random即:java.util.Random,
ThreadLocalRandom 即:java.util.concurrent.ThreadLocalRandom
SecureRandom即:java.security.SecureRandom


Q:Random是不是線程安全的?
A:Random是線程安全的,但是多線程下可能性能比較低。
參考:
https://docs.oracle.com/javase/7/docs/api/java/util/Random.html
https://stackoverflow.com/questions/5819638/is-random-class-thread-safe

Q:ThreadLocalRandom為什麼這麼快?
A:其實這個看下源碼就知道了。。因為Random用了很多CAS的類,ThreadLocalRandom根本沒有用到。

Q:為什麼在高強度要求的情況下,不要用Random?

A:特別是在生成驗證碼的情況下,不要使用Random,因為它是線性可預測的。記得有個新聞說的是一個賭博網站,為了說明其公平,公開的它的源代碼,結果因為隨機數可預測漏洞被攻擊了。所以在安全性要求比較高的場合,應當使用SecureRandom。

update 2014-4-22:  https://news.cnblogs.com/n/206074/

參考:https://www.inbreak.net/archives/349

Q:從理論上來說計算機產生的隨機數都是偽隨機數,那麼如何產生高強度的隨機數?
A:產生高強度的隨機數,有兩個重要的因素:種子和算法。當然算法是可以有很多的,但是如何選擇種子是非常關鍵的因素。如Random,它的種子是System.currentTimeMillis(),所以它的隨機數都是可預測的。那麼如何得到一個近似隨機的種子?這裏有一個很別致的思路:收集計算機的各種信息,如鍵盤輸入時間,CPU時鍾,內存使用狀態,硬盤空閑空間,IO延時,進程數量,線程數量等信息,來得到一個近似隨機的種子。這樣的話,除了理論上有破解的可能,實際上基本沒有被破解的可能。而事實上,現在的高強度的隨機數生成器都是這樣實現的。
比如Windows下的隨機數生成器:
https://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx
https://msdn.microsoft.com/en-us/library/aa379942%28VS.85%29.aspx
Linux下的 /dev/random:
https://zh.wikipedia.org/wiki//dev/random
據SecureRandom的Java doc,說到在類unix係統下,有可能是利用 /dev/random,來實現的。


其它的一些有意思的東東:
最快的安全性要求不高的生成UUID的方法(注意,強度不高,有可能會重複):
new UUID(ThreadLocalRandom.current().nextLong(), ThreadLocalRandom.current().nextLong());
在一個網站上看到的,忘記出處了。


隨機生成產生隨機數的函數?
是否可以利用一個隨機數生成器來生成一係列的隨機代碼,然後作為一個新的隨機數生成器?貌似強度是傳遞的,似乎沒意義。


最後更新:2017-04-03 14:54:32

  上一篇:go 不用重新配置,用jconsole連接遠程機器進程及獲得本地進程的JMX Url的終極辦法
  下一篇:go android多線程下載2