- apk被拉去阿里云檢查,出來高危漏洞
使用SecureRandom時不要使用SecureRandom (byte[] seed)這個構造函數,會造成生成的隨機數不隨機。
建議通過/dev/urandom或者/dev/random獲取的熵值來初始化偽隨機數生成器PRNG高危
看到這個就想研究下隨機數。
- 分類
- 真隨機數,通過物理實驗得出,比如擲錢幣、骰子、轉輪、使用電子元件的噪音、核裂變等
- 偽隨機數,通過一定算法和種子得出。軟件實現的是偽隨機數
- 強偽隨機數,難以預測的隨機數
- 弱偽隨機數,易于預測的隨機數
- 結果對比
-
真隨機數RANDOM.ORG
-
真隨機數
-
偽隨機數PHP rand() on Microsoft Windows
- Java產生隨機數方法
- Math.random(),偽隨機數
- java.util.Random 偽隨機數(線性同余法生成)
- java.security.SecureRandom 真隨機數
- 示例代碼
package remdo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.security.SecureRandom;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
/**
* 測試1-100內的隨機數,
*
* @author Wilson
*
*/
public class RamdonTest {
public static List<Integer> getMath(int bound) {
List<Integer> list=new ArrayList<>();
if (bound > 1) {
for (int i = 0; i < bound; i++) {
int mathInt = (int) Math.random() * bound;
list.add(mathInt);
}
}
return list;
}
public static List<Integer> getRandom(int bound) {
List<Integer> list=new ArrayList<>();
if (bound > 1) {
Random random = new Random();
for (int i = 0; i < bound; i++) {
int mathRandom = random.nextInt(bound);
list.add(mathRandom);
}
}
return list;
}
public static List<Integer> getSecureRandom(int bound) {
List<Integer> list=new ArrayList<>();
if (bound > 1) {
SecureRandom secureRandom = new SecureRandom();
for (int i = 0; i < bound; i++) {
//推薦
int mathRandom = secureRandom.nextInt(bound);
list.add(mathRandom);
}
}
return list;
}
public static void printTotal(List<Integer> list) {
Map<Integer, Integer> map = new HashMap<>();
for (Integer integer : list) {
int count=1;
if (map.containsKey(integer)) {
count=map.get(integer)+1;
}
map.put(integer, count);//插入新的數據
}
//遍歷hashmap,遍歷方式較list要麻煩一點,誰叫他功能更豐富
Iterator<Entry<Integer, Integer>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Entry<Integer, Integer> entry = (Entry<Integer, Integer>) iterator.next();
System.out.println("隨機數:" + entry.getKey() + ",被隨機中的次數:" + entry.getValue() + "次");
}
}
public static void test() {
Random r = new Random(); //5000作為seed,默認使用當前時間作為seed
//固定種子,可是產生隨機數是固定的,
r.setSeed(5000);
for (int i=0;i<5;++i)
{
System.out.println(+r.nextInt()*500);
}
}
public static void testSCR() {
SecureRandom r = new SecureRandom(); //5000作為seed,默認使用當前時間作為seed
//固定種子,可是產生的隨機數是隨機的
r.setSeed(5000);
for (int i=0;i<5;++i)
{
System.out.println(r.nextInt());
}
}
public static void main(String[] args) {
// RamdonTest.printTotal(RamdonTest.getMath(100));
// RamdonTest.printTotal(RamdonTest.getRandom(100));
// RamdonTest.printTotal(RamdonTest.getRandom(100));
// RamdonTest.printTotal(RamdonTest.getSecureRandom(1000));
// RamdonTest.test();
RamdonTest.testSCR();
//Random和SecureRandom對比,只要知道Random的種子就能預測到隨機數結果,具體可對比test()和testSCR()產生隨機數
}
}