自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們一起聊聊 Java 隨機(jī)數(shù)的種子

開發(fā) 前端
假設(shè)在一個非??臻e的機(jī)器上,SecureRandom?使用高熵值可能會使服務(wù)卡死,機(jī)器沒有足夠的隨機(jī)信息,SecureRandom無法生成種子,就難以運(yùn)行了。

在許多領(lǐng)域,比如模擬、游戲和密碼學(xué)中,隨機(jī)數(shù)擔(dān)任非常重要的角色。

然而,在計算機(jī)領(lǐng)域,隨機(jī)數(shù)并非完全隨機(jī),它們是由模擬隨機(jī)性的算法(稱為偽隨機(jī)性)生成的。

在Java中,隨機(jī)種子就是初始化偽隨機(jī)數(shù)生成器(PRNG,Pseudo Random Number Generator)的值。

我們一起探討下,Java中隨機(jī)種子的工作原理,以及如何使用它生成可預(yù)測的數(shù)字序列。

一、什么是隨機(jī)種子?

隨機(jī)種子是設(shè)置PRNG(偽隨機(jī)數(shù)生成器)內(nèi)部狀態(tài)的初始值。

默認(rèn)情況下,如果我們指定種子值,Java的Random類會使用系統(tǒng)時鐘作為種子值。這樣做的好處是,確保了每次創(chuàng)建新的Random對象時,生成的數(shù)字序列都是不同的,增加了隨機(jī)性。

如果我們提供特定的種子值,每次都會生成相同的“隨機(jī)”數(shù)字序列。這在我們需要可重復(fù)性的情況下非常有用,比如測試、調(diào)試或需要結(jié)果一致性的模擬場景。

有了種子值之后,PRNG算法會基于種子值生成一系列數(shù)字。

每次我們調(diào)用nextInt()、nextDouble()或類似方法時,它都會更新生成器的內(nèi)部狀態(tài),從而保證每次生成一個新數(shù)字。但是,如果使用相同的種子,生成的數(shù)字序列將始終相同。

接下來我們看下這兩種情況。

二、不使用種子生成隨機(jī)數(shù)

Java提供了java.util.Random類,用于生成隨機(jī)數(shù)。

當(dāng)我們創(chuàng)建一個Random實(shí)例而不指定種子時,Java會使用系統(tǒng)時鐘為生成器設(shè)定種子。這意味著每次運(yùn)行都會產(chǎn)生不同的序列。例如:

import java.util.Random;

public class RandomWithoutSeed {
    public static void main(String[] args) {
        Random random = new Random();
        // 生成7個隨機(jī)整數(shù)
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        Random random2 = new Random();
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random2.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        Random random3 = new Random();
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random3.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
    }
}

在這個例子中,每次運(yùn)行都會生成不同的隨機(jī)整數(shù)序列,因?yàn)榉N子是根據(jù)當(dāng)前時間自動設(shè)置的。

第一次運(yùn)行結(jié)果是:

76 	9 	11 	77 	67 	91 	91
76 	44 	28 	5 	91 	59 	30
41 	18 	72 	14 	6 	4 	63

在運(yùn)行一次:

33 	65 	97 	31 	94 	19 	1
97 	2 	40 	58 	9 	33 	57
46 	82 	21 	94 	54 	36 	79

可以看出來,結(jié)果基本上符合隨機(jī)性。(上面的結(jié)果只是展示下隨機(jī)效果,每次運(yùn)行都會有差異)

三、使用種子生成隨機(jī)數(shù)

當(dāng)我們提供特定的種子時,生成的數(shù)字序列在不同的運(yùn)行中是可預(yù)測且一致的。

import java.util.Random;

public class RandomWithSeed {
    public static void main(String[] args) {
        Random random = new Random(12345L); // 種子設(shè)置為12345
        // 生成7個隨機(jī)整數(shù)
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        Random random2 = new Random(12345L); // 種子設(shè)置為12345
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random2.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        Random random3 = new Random(12345L); // 種子設(shè)置為12345
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random3.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
    }
}

在這里,Random類的構(gòu)造函數(shù)接受一個種子值作為參數(shù),在這個例子中,種子被設(shè)置為12345L(一個特定的長整型值)。

這個種子初始化偽隨機(jī)數(shù)生成器(PRNG),重要的是,它確保如果程序使用相同的種子運(yùn)行,將始終生成相同的數(shù)字序列。

第一次運(yùn)行結(jié)果是:

51 	80 	41 	28 	55 	84 	75
51 	80 	41 	28 	55 	84 	75
51 	80 	41 	28 	55 	84 	75

再來一次還是這樣:

51 	80 	41 	28 	55 	84 	75
51 	80 	41 	28 	55 	84 	75
51 	80 	41 	28 	55 	84 	75

所以說,“隨機(jī)”是可以操縱的。

四、使用SecureRandom

在密碼學(xué)應(yīng)用中,使用可預(yù)測的隨機(jī)數(shù)可能會導(dǎo)致安全漏洞。

Java提供了SecureRandom類用于生成密碼學(xué)安全的隨機(jī)數(shù)。

看名字就知道,SecureRandom安全等級高一些。

import java.security.SecureRandom;

public class SecureRandomExample {
    public static void main(String[] args) throws Exception {
        SecureRandom random = new SecureRandom(new byte[] {1, 2, 3, 4, 5});
        // 生成7個隨機(jī)整數(shù)
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        SecureRandom random2 = new SecureRandom(new byte[] {1, 2, 3, 4, 5});
        // 生成7個隨機(jī)整數(shù)
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random2.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
        System.out.println();

        SecureRandom random3 = new SecureRandom(new byte[] {1, 2, 3, 4, 5});
        // 生成7個隨機(jī)整數(shù)
        for (int i = 0; i < 7; i++) {
            System.out.format("%d \t", random3.nextInt(100)); // 0到99之間的隨機(jī)整數(shù)
        }
    }
}

上面的例子中,我們傳入相同的種子,運(yùn)行結(jié)果也是隨機(jī)的。

第一次運(yùn)行:

78 	68 	56 	24 	73 	13 	88
24 	14 	20 	69 	25 	4 	61
25 	8 	32 	39 	25 	16 	87

第二次運(yùn)行:

4 	35 	46 	26 	48 	92 	66
83 	92 	28 	64 	13 	75 	44
60 	79 	81 	52 	7 	66 	11

結(jié)果也是足夠隨機(jī)的。(上面的結(jié)果只是展示下隨機(jī)效果,每次運(yùn)行都會有差異)

SecureRandom使用高熵值的源來初始化其內(nèi)部狀態(tài)。熵是對不確定性或隨機(jī)性的度量,高熵源意味著具有更多的隨機(jī)性。常見的熵源包括:

  • 操作系統(tǒng)提供的隨機(jī)數(shù)據(jù):許多操作系統(tǒng)都有內(nèi)置的隨機(jī)數(shù)生成器,它們從硬件設(shè)備(如鼠標(biāo)移動、鍵盤敲擊時間間隔、磁盤 I/O 操作等)收集隨機(jī)事件產(chǎn)生的數(shù)據(jù),這些數(shù)據(jù)具有較高的隨機(jī)性,SecureRandom可以從中獲取種子或隨機(jī)數(shù)據(jù)來初始化自身。
  • 硬件隨機(jī)數(shù)生成器:某些計算機(jī)系統(tǒng)配備了專門的硬件設(shè)備來生成真正的隨機(jī)數(shù),例如基于熱噪聲、放射性衰變等物理現(xiàn)象的硬件隨機(jī)數(shù)生成器。這些硬件設(shè)備能夠產(chǎn)生高質(zhì)量的隨機(jī)數(shù),SecureRandom可以直接使用或結(jié)合這些硬件生成的隨機(jī)數(shù)來增強(qiáng)隨機(jī)性。

SecureRandom會維護(hù)一個內(nèi)部狀態(tài),該狀態(tài)在每次生成隨機(jī)數(shù)時都會更新。新生成的隨機(jī)數(shù)不僅取決于當(dāng)前的熵源數(shù)據(jù),還與之前的內(nèi)部狀態(tài)有關(guān)。這種狀態(tài)更新機(jī)制使得生成的隨機(jī)數(shù)序列更加難以預(yù)測,即使攻擊者獲取了部分隨機(jī)數(shù),也難以推斷出后續(xù)的隨機(jī)數(shù)。

與普通的Random類不同,SecureRandom對種子的管理更為嚴(yán)格。它可以自動從可靠的熵源獲取種子,以確保每次初始化時都有足夠的隨機(jī)性。

雖然允許用戶提供種子,但通常建議讓系統(tǒng)自動管理種子,以充分利用高質(zhì)量的熵源。

需要注意的是,假設(shè)在一個非??臻e的機(jī)器上,SecureRandom使用高熵值可能會使服務(wù)卡死,機(jī)器沒有足夠的隨機(jī)信息,SecureRandom無法生成種子,就難以運(yùn)行了。

責(zé)任編輯:武曉燕 來源: 看山的小屋
相關(guān)推薦

2022-12-06 08:12:11

Java關(guān)鍵字

2025-03-27 02:00:00

SPIJava接口

2022-07-29 08:17:46

Java對象內(nèi)存

2023-04-26 07:30:00

promptUI非結(jié)構(gòu)化

2023-08-04 08:20:56

DockerfileDocker工具

2022-05-24 08:21:16

數(shù)據(jù)安全API

2023-08-10 08:28:46

網(wǎng)絡(luò)編程通信

2023-09-10 21:42:31

2023-06-30 08:18:51

敏捷開發(fā)模式

2022-10-08 00:00:05

SQL機(jī)制結(jié)構(gòu)

2021-08-27 07:06:10

IOJava抽象

2024-02-20 21:34:16

循環(huán)GolangGo

2023-11-10 08:04:43

Java 17Java 11JDK

2022-09-08 08:50:17

SSDOracleCPU

2024-06-14 09:32:12

2023-08-02 08:35:54

文件操作數(shù)據(jù)源

2024-09-09 08:53:56

2025-04-11 00:05:49

RPC底層分布式

2023-03-07 07:05:29

生產(chǎn)數(shù)據(jù)庫運(yùn)維

2021-07-31 11:40:55

Openresty開源
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號