日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

PHP中的随机性——你觉得自己幸运吗?

發(fā)布時(shí)間:2025/3/20 php 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PHP中的随机性——你觉得自己幸运吗? 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文分析了生成用于加密的隨機(jī)數(shù)的相關(guān)問(wèn)題。?PHP?5沒(méi)有提供一種簡(jiǎn)單的機(jī)制來(lái)生成密碼學(xué)上強(qiáng)壯的隨機(jī)數(shù),但是PHP?7通過(guò)引入幾個(gè)CSPRNG函數(shù)來(lái)解決了這個(gè)問(wèn)題。

什么是CSPRNG

引用維基百科,一個(gè)密碼學(xué)上安全的偽隨機(jī)數(shù)發(fā)生器(Cryptographically?Secure?Pseudorandom?Number?Generator?縮寫(xiě)CSPRNG)是一個(gè)偽隨機(jī)數(shù)生成器(PRNG),其生成的偽隨機(jī)數(shù)適用于密碼學(xué)算法。

CSPRNG可能主要用于:

  • 密鑰生成(例如,生成復(fù)雜的密鑰)

  • 為新用戶產(chǎn)生隨機(jī)的密碼

  • 加密系統(tǒng)

獲得高級(jí)別安全性的一個(gè)關(guān)鍵方面就是高品質(zhì)的隨機(jī)性

PHP7?中的CSPRNG

PHP?7引入了兩個(gè)新函數(shù)可以用來(lái)實(shí)現(xiàn)CSPRNG:?random_bytes?和?random_int。

random_bytes?函數(shù)返回一個(gè)字符串,接受一個(gè)int型入?yún)⒋矸祷亟Y(jié)果的字節(jié)數(shù)。

例子:

  • $bytes?=?random_bytes('10');?
  • var_dump(bin2hex($bytes));?
  • //possible?ouput:?string(20)?"7dfab0af960d359388e6"?
  • random_int?函數(shù)返回一個(gè)指定范圍內(nèi)的int型數(shù)字。

    例子:

  • var_dump(random_int(1,?100));?
  • //possible?output:?27?
  • 后臺(tái)運(yùn)行環(huán)境

    以上函數(shù)的隨機(jī)性不同的取決于環(huán)境:

    • 在window上,CryptGenRandom()總是被使用。

    • 在其他平臺(tái),arc4random_buf()如果可用會(huì)被使用(在BSD系列或者具有l(wèi)ibbsd的系統(tǒng)上成立)

    • 以上都不成立的話,一個(gè)linux系統(tǒng)調(diào)用getrandom(2)會(huì)被使用。

    • 如果還不行,/dev/urandom?會(huì)被作為最后一個(gè)可使用的工具

    • 如果以上都不行,系統(tǒng)會(huì)拋出錯(cuò)誤

    一個(gè)簡(jiǎn)單的測(cè)試

    一個(gè)好的隨機(jī)數(shù)生成系統(tǒng)保證合適的產(chǎn)生“質(zhì)量”。為了檢查這個(gè)質(zhì)量,?通常要執(zhí)行一連串的統(tǒng)計(jì)測(cè)試。不需要深入研究復(fù)雜的統(tǒng)計(jì)主題,比較一個(gè)已知的行為和數(shù)字生成器的結(jié)果可以幫助質(zhì)量評(píng)價(jià)。

    一個(gè)簡(jiǎn)單的測(cè)試是骰子游戲。假設(shè)擲1個(gè)骰子1次得到結(jié)果為6的概率是1/6,那么如果我同時(shí)擲3個(gè)骰子100次,得到的結(jié)果粗略如下:

    • 0?個(gè)6?=?57.9?次

    • 1?個(gè)6?=?34.7次

    • 2?個(gè)6?=?6.9次

    • 3?個(gè)6?=?0.5次

    以下是是實(shí)現(xiàn)實(shí)現(xiàn)擲骰子1,000,000次的代碼:

  • $times?=?1000000;?
  • $result?=?[];?
  • for?($i=0;?$i<$times;?$i++){?
  • ????$dieRoll?=?array(6?=>?0);?//initializes?just?the?six?counting?to?zero?
  • ????$dieRoll[roll()]?+=?1;?//first?die?
  • ????$dieRoll[roll()]?+=?1;?//second?die?
  • ????$dieRoll[roll()]?+=?1;?//third?die?
  • ????$result[$dieRoll[6]]?+=?1;?//counts?the?sixes?
  • }?
  • function?roll(){?
  • ????return?random_int(1,6);?
  • }?
  • var_dump($result);?
  • 用PHP7?的?random_int?和簡(jiǎn)單的?rand?函數(shù)可能得到如下結(jié)果

    Sixes

    expected

    random_int

    0

    579000

    579430

    1

    347000

    346927

    2

    69000

    68985

    3

    5000

    4658

    如果先看到rand?和?random_int?更好的比較我們可以應(yīng)用一個(gè)公式把結(jié)果畫(huà)在圖上。公式是:(php結(jié)果-期待的結(jié)果)/期待結(jié)果的0.5次方。

    結(jié)果圖如下:

    (接近0的值更好)

    盡管3個(gè)6的結(jié)果表現(xiàn)不好,并且這個(gè)測(cè)試對(duì)實(shí)際應(yīng)用來(lái)說(shuō)太過(guò)簡(jiǎn)單我們?nèi)钥梢钥闯?random_int?表現(xiàn)優(yōu)于?rand.

    進(jìn)一步,我們的應(yīng)用的安全級(jí)別由于不可預(yù)測(cè)性和隨機(jī)數(shù)發(fā)生器的可重復(fù)行為而得到提升。

    PHP5?呢

    缺省情況下,PHP5?不提供強(qiáng)壯的隨機(jī)數(shù)發(fā)生器。實(shí)際上,還是有選擇的比如?openssl_random_pseudo_bytes(),?mcrypt_create_iv()?或者直接使用fread()函數(shù)來(lái)使用?/dev/random?或?/dev/urandom?設(shè)備。也有一些包比如?RandomLib?或?libsodium.

    如果你想要開(kāi)始使用一個(gè)更好的隨機(jī)數(shù)發(fā)生器并且同時(shí)準(zhǔn)備好使用PHP7,你可以使用Paragon?Initiative?Enterprises?random_compat?庫(kù)。?random_compat?庫(kù)允許你在?PHP?5.x?project.使用?random_bytes()?and?random_int()

    這個(gè)庫(kù)可以通過(guò)Composer安裝:

  • composer?require?paragonie/random_compat?
  • ?
  • require?'vendor/autoload.php';?
  • $string?=?random_bytes(32);?
  • var_dump(bin2hex($string));?
  • //?string(64)?"8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f"?
  • $int?=?random_int(0,255);?
  • var_dump($int);?
  • //?int(81)?
  • random_compat?庫(kù)和PHP7使用不同的順序:

  • fread()?/dev/urandom?if?available?
  • mcrypt_create_iv($bytes,?MCRYPT_CREATE_IV)?
  • COM('CAPICOM.Utilities.1')->GetRandom()?
  • openssl_random_pseudo_bytes()?
  • 想知道為什么是這個(gè)順序建議閱讀?documentation.

    這個(gè)庫(kù)的一個(gè)簡(jiǎn)單應(yīng)用用來(lái)產(chǎn)生密碼:

  • $passwordChar?=?'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';?
  • $passwordLength?=?8;?
  • $max?=?strlen($passwordChar)?-?1;?
  • $password?=?'';?
  • for?($i?=?0;?$i?<?$passwordLength;?++$i)?{?
  • ????$password?.=?$passwordChar[random_int(0,?$max)];?
  • }?
  • echo?$password;?
  • //possible?output:?7rgG8GHu?
  • 總結(jié)

    你總是應(yīng)該使用一個(gè)密碼學(xué)上安全的偽隨機(jī)數(shù)生成器,random_compat?庫(kù)提供了一種好的實(shí)現(xiàn)。

    如果你想要使用可靠的隨機(jī)數(shù)據(jù)源,如你在本文所見(jiàn),建議盡快使用?random_int?和?random_bytes.


    作者:邱康

    來(lái)源:51CTO

    總結(jié)

    以上是生活随笔為你收集整理的PHP中的随机性——你觉得自己幸运吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。