c++ - 如何在同一个 srand() 种子中获得两个不同的随机数?C++
问题描述
我正在尝试创建一个随机密码生成器。当我多次调用该函数时,它返回相同的字符值。QQpQ;7Q7pQ;p
我尝试在我的主要功能中添加srand(time(0));
或。srand((unsigned int) time(NULL));
查看其他 stack over flow 帖子,我发现 srand 每次运行程序时都有助于创建不同的字符。但是它仍然返回相同字符的倍数。
如何在运行时更改 srand() 种子以获得不同的随机数?
#include <string>
#include <iostream>
#include <time.h>
using namespace std;
string randomGenerator(int numberOfCharacters);
char randomCapitalCharacter();
char randomLowerCharacter();
char randomSpecialCharacter();
char randomInt();
int main(){
srand((unsigned int) time(NULL));
int passwordLength = 12;
string password = randomGenerator(passwordLength);
cout << password << endl;
return 0;
}
string randomGenerator(int numberOfCharacters){
char randomCharacterTypes[4] = {randomLowerCharacter(),randomInt(), randomCapitalCharacter(), randomSpecialCharacter()};
std::string password;
while (numberOfCharacters > 0){
int random = rand()%4;
password += randomCharacterTypes[random];
numberOfCharacters--;
}
return password;
}
char randomInt(){
std::string numberAsString = to_string(std::rand()% 10);
char randomNumberChar = numberAsString.at(0);
return randomNumberChar;
}
char randomLowerCharacter(){
return 97 + rand()%26; //97 = a
}
char randomCapitalCharacter(){
return 65 + rand()%26; //65 = A
}
char randomSpecialCharacter(){
/** Special characters are split by numbers so we pick a random from one of the 2 groups.*/
return (rand()%2) ? char(33 + rand()%14) : char(58 + rand()%8);
}
解决方案
randomCharacterTypes
是一个由 4 个字符组成的数组,对于每个字符类,您总是会得到相同的字符。如果您想每次都生成一个新字符,则可以使用函数指针:
string randomGenerator(int numberOfCharacters){
char (*randomCharacterTypes[])() = {randomLowerCharacter,randomInt, randomCapitalCharacter, randomSpecialCharacter};
std::string password;
while (numberOfCharacters > 0){
int random = rand()%4;
password += randomCharacterTypes[random]();
numberOfCharacters--;
}
return password;
}
randomInt
可以简化为返回'0'
与'9'
其他函数相同的字符:
char randomInt(){
return '0' + rand() % 10;
}
如果您使用字符而不是数字,则您的其他函数更具可读性,然后您必须添加注释以提醒您它们代表的字符:
char randomLowerCharacter(){
return 'a' + rand()%26;
}
char randomCapitalCharacter(){
return 'A' + rand()%26;
}
char randomSpecialCharacter(){
/** Special characters are split by numbers so we pick a random from one of the 2 groups.*/
return (rand()%2) ? char('!' + rand()%14) : char(':' + rand()%8);
}
请注意,这rand() % x
不是一个好的随机数生成器,您应该改用标准库随机函数(特别是如果您将这些密码用于任何重要的事情)。
string
使用s 包含您的字符类可能会进一步简化您的代码:
#include <string>
#include <string_view>
#include <iostream>
#include <random>
#include <array>
class PasswordGenerator
{
public:
PasswordGenerator()
{
for (size_t i = 0; i < characterTypes.size(); i++)
{
characterTypeDistributions[i] = std::uniform_int_distribution<int>(0, characterTypes[i].size() - 1);
}
}
static constexpr std::array<std::string_view, 4> characterTypes = {
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"!\"#$%&'()*+,-./:;<=>?@"
};
std::array<std::uniform_int_distribution<int>, characterTypes.size()> characterTypeDistributions;
std::uniform_int_distribution<int> typeDistribution{0, characterTypes.size() - 1};
std::mt19937 eng{std::random_device{}()};
std::string generate(int numberOfCharacters){
std::uniform_int_distribution<int> dist{0, 5};
std::string password;
password.reserve(numberOfCharacters);
for (int i = 0; i < numberOfCharacters; i++)
{
auto type = typeDistribution(eng);
password += characterTypes[type][characterTypeDistributions[type](eng)];
}
return password;
}
};
int main(){
int passwordLength = 12;
PasswordGenerator gen;
std::string password = gen.generate(passwordLength);
std::cout << password << "\n";
return 0;
}
请注意,此代码可能仍不符合生成密码的高安全标准。
推荐阅读
- html - 从 innerHTML 获取 href
- javascript - 指针事件不会通过 javascipt 切换?
- javascript - 如何无限淡入淡出线性渐变背景图片和文字
- c# - 使用 Ef Core 选择分层数据中的特定列
- reactjs - 表格标签在反应降价中没有突出显示或呈现
- mongodb - 在比较那些重复项中的某些字段时在 MongoDB 中查找重复项
- .net-core - 如何使用 IHttpClientFactory 在 Blazor Server 中配置 HttpClient 基地址
- java - 网页辅助功能:输入需要用键盘检查 Enter 键按下
- excel - 动态嵌套excel公式
- java - RabbitMQ 异常:操作 queue.declare 导致服务器端出现通道异常 not_found