如何在同一个 srand() 种子中获得两个不同的随机数? C++
How do I get two different random numbers in the same srand() seed? C++
我正在尝试创建一个随机密码生成器。当我多次调用该函数时,它 returns 相同的字符值。 QQpQ;7Q7pQ;p
我已经尝试在我的主函数中添加 srand(time(0));
或 srand((unsigned int) time(NULL));
。
查看其他 stack over flow 帖子时,我发现每次 运行 程序时 srand 都有助于创建不同的字符。但是它仍然是相同字符的 returns 倍数。
如何在 运行 时间内更改 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);
}
- srand() — why call it only once?
- Why does rand() yield the same sequence of numbers on every run?
感谢@RetiredNinja 指出问题不在于 srand(),而在于我的数组中的函数调用不当。使用 switch 语句调用函数正确解决了这个问题。
//improper calling of functions in an array. Resolved with switch statement below
//char randomCharacterTypes[4] = {randomLowerCharacter(),randomInt(), randomCapitalCharacter(), randomSpecialCharacter()};
while (numberOfCharacters > 0){
int random = rand()%4;
switch(random){
case 0:
password += randomLowerCharacter();
break;
case 1:
password += randomInt();
break;
case 2:
password += randomCapitalCharacter();
break;
case 3:
password += randomSpecialCharacter();
break;
}
numberOfCharacters--;
}
randomCharacterTypes
是一个包含 4 个字符的数组,对于每个字符 class,您将始终得到相同的字符。如果你想每次都生成一个新字符,你可以使用函数指针代替:
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
可以简化为 return '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);
}
请注意 不是一个好的随机数生成器,您应该改用标准库随机函数(特别是如果您将这些密码用于任何重要的事情)。
您的代码可能会进一步简化,使用 string
s 来包含您的角色 classes:
#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;
}
请注意,此代码可能仍不符合生成密码的高安全标准。
我正在尝试创建一个随机密码生成器。当我多次调用该函数时,它 returns 相同的字符值。 QQpQ;7Q7pQ;p
我已经尝试在我的主函数中添加 srand(time(0));
或 srand((unsigned int) time(NULL));
。
查看其他 stack over flow 帖子时,我发现每次 运行 程序时 srand 都有助于创建不同的字符。但是它仍然是相同字符的 returns 倍数。
如何在 运行 时间内更改 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);
}
- srand() — why call it only once?
- Why does rand() yield the same sequence of numbers on every run?
感谢@RetiredNinja 指出问题不在于 srand(),而在于我的数组中的函数调用不当。使用 switch 语句调用函数正确解决了这个问题。
//improper calling of functions in an array. Resolved with switch statement below
//char randomCharacterTypes[4] = {randomLowerCharacter(),randomInt(), randomCapitalCharacter(), randomSpecialCharacter()};
while (numberOfCharacters > 0){
int random = rand()%4;
switch(random){
case 0:
password += randomLowerCharacter();
break;
case 1:
password += randomInt();
break;
case 2:
password += randomCapitalCharacter();
break;
case 3:
password += randomSpecialCharacter();
break;
}
numberOfCharacters--;
}
randomCharacterTypes
是一个包含 4 个字符的数组,对于每个字符 class,您将始终得到相同的字符。如果你想每次都生成一个新字符,你可以使用函数指针代替:
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
可以简化为 return '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);
}
请注意
您的代码可能会进一步简化,使用 string
s 来包含您的角色 classes:
#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;
}
请注意,此代码可能仍不符合生成密码的高安全标准。