一、QT隨機數簡介
QT是一個跨平台的C++開發框架,其中包含了很多有用的類、函數庫,其中包含了產生隨機數的函數。
QRandomGenerator::global()->generate();
這個函數會返回一個無符號的隨機數,並且可以設定隨機數的範圍,如下:
QRandomGenerator::global()->bounded(10); // 返回一個0~9之間的數 QRandomGenerator::global()->bounded(1, 11); // 返回一個1~10之間的數
二、隨機數發生器的初始化
在使用隨機數發生器前,需要進行初始化操作,一般使用設備存儲的熵來進行初始化,如下:
QRandomGenerator randGen(QDateTime::currentMSecsSinceEpoch() ^
static_cast<quint64>(reinterpret_cast<quintptr>(QThread::currentThread())));
randGen.generate();
這裡使用了系統時間和當前線程的地址進行異或操作,確保初始化的唯一性。
三、隨機數應用場景舉例
1、遊戲開發
遊戲開發中經常需要用到隨機數,如隨機生成地形、怪物屬性、物品掉落等等。
// 隨機生成怪物血量 int maxHP = 1000; int minHP = 500; int randHP = randGen.bounded(minHP, maxHP+1); Monster monster(randHP);
2、密碼學
密碼學中需要用到隨機數來確保密碼的安全性,如RSA演算法中產生密鑰需要用到隨機數。
// 產生一個1024位的隨機素數
QCryptographicHash hash(QCryptographicHash::Sha3_512);
while (true) {
qint64 num = QRandomGenerator::global()->bounded(1e16, 1e17);
hash.addData(QByteArray::number(num));
QByteArray bytes = hash.result().left(128);
BIGNUM* prime = BN_bin2bn((const unsigned char*)bytes.constData(), bytes.size(), NULL);
if (BN_is_prime(prime, BN_prime_checks, NULL, NULL, NULL, NULL)) {
BIGNUM* zero = BN_new();
BN_zero(zero);
RSA* rsa = RSA_new();
rsa->n = prime;
BIGNUM* e = BN_new();
BN_set_word(e, RSA_F4);
rsa->e = e;
rsa->d = BN_mod_inverse(NULL, e, rsa->n, NULL);
rsa->p = zero;
rsa->q = zero;
rsa->dmp1 = zero;
rsa->dmq1 = zero;
rsa->iqmp = zero;
break;
}
}
3、數據加密
數據加密中經常需要用到隨機數生成初始化向量(IV),用來確保加密的安全性。
// AES加密 QByteArray key; QByteArray iv = RandGen.generate(16); QByteArray cipher = QCryptographicHash::hash(rawData, QCryptographicHash::Md5).toHex(); QAESEncryption crypto(QAESEncryption::AES_256, QAESEncryption::ECB); QByteArray encrypted = crypto.encode(rawData, key, iv);
4、畫圖應用
畫圖應用中也需要用到隨機數,如隨機生成各種圖形。
// 隨機生成一些點
QPainter painter(&image);
for (int i = 0; i < 1000; ++i) {
int x = randGen.bounded(0, image.width());
int y = randGen.bounded(0, image.height());
painter.drawEllipse(x, y, 1, 1);
}
四、注意事項
使用隨機數時需要注意一些事項,如唯一性、安全性等等。
1、唯一性
在某些應用場景下,需要確保產生的隨機數唯一,如生成訂單號、用戶ID等等。
// 隨機生成一個唯一的ID quint64 randID = QDateTime::currentMSecsSinceEpoch() ^ static_cast<quint64>(reinterpret_cast<quintptr>(QThread::currentThread()));
2、安全性
在密碼學、數據加密等領域使用隨機數時需要注意安全性問題,需要使用高質量的隨機數發生器,如硬體隨機數發生器。
// 使用硬體隨機數發生器
QByteArray data;
if (QRandomGenerator::securelySeeded()) {
data.resize(16);
if (RAND_bytes((unsigned char*)data.constData(), data.size()) != 1) {
qWarning() << "RAND_bytes failed";
}
}
3、分布
隨機數發生器產生的數不一定符合某些分布,如正態分布、均勻分布等等,需要進行轉換處理。
// 產生正態分布隨機數 double mean = 10.0; double stddev = 2.0; double randNum = mean + NormRand()*stddev;
五、總結
QT提供了一系列有用的隨機數發生器,可以應用到各種領域,同時需要注意隨機數的唯一性、安全性和分布問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/187581.html
微信掃一掃
支付寶掃一掃