简介
随机数的使用越来越广泛。
除了加密领域,在日常生活中也随处可见。如抽签、抽奖、测试等。
这里描述一个与Redis使用有关的场景:Redis过期时间的设置。
即建议对大批量的数据过期时间,设置一个值,并加上一个随机值,防止批量数据同时失效,造成缓存雪崩或影响性能。
c++11
c++11引入了头文件,用于生成随机数。它包括两个部分:
- random engine: 生成随机的bit流
- distribution: 生成满足用户需求的随机数
用法如下:
- 使用seed初始化random engine,推荐std::random_device
- 它每次运行都会生成不同的随机bit流
- 如果要在每次启动时生成相同的序列,则需要用常量int初始化
- 使用min-max范围值初始化distribution对象
c++11示例
下面直接上代码,使用 uniform_int_distribution 并输出10个1-100范围内的随机数字。
#include <iostream>
#include <random>
using std::cout;
using std::endl;
constexpr int MIN = 1;
constexpr int MAX = 100;
constexpr int RAND_NUMS_TO_GENERATE = 10;
int main()
{
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int n = 0; n < RAND_NUMS_TO_GENERATE; ++n) {
cout << distr(eng) << "; ";
}
cout << endl;
return 0;
}
输出如下:
``
也可以指定random engine(不同的random engine具有不同的算法或性能差异)。
代码片断如下:
std::random_device rd;
std::mt19937 eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
c函数random
它的随机数质量可能不如前述,但在很多场合也够用了。
用法如下:
- 以std::srand生成种子(一般以std::time(nullptr)为参数)
- 调用rand生成随机数
代码如下:
#include <iostream>
#include <random>
#include <ctime>
using std::cout;
using std::endl;
constexpr int MIN = 1;
constexpr int MAX = 100;
constexpr int RAND_NUMS_TO_GENERATE = 10;
int main()
{
std::srand(std::time(nullptr));
for (int i = 0; i < RAND_NUMS_TO_GENERATE; i++)
cout << rand() % MAX << "; ";
cout << endl;
return 0;
}
小结
建议直接使用第一种代码示例,在大多数场景下是可以满足需求的。
当然,使用代码生成的随机数都是伪随机数,真正的密码领域需要使用硬件辅助了。