目前将矢量转换为字符串的密码生成器问题 [英] password generator issue at the moment to convert vector to string

查看:40
本文介绍了目前将矢量转换为字符串的密码生成器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图随机生成密钥,并在密钥后加入一些连字符,但是当我尝试这样做时,我没有从 :: vector< std :: string中得到合适的用户定义转换,std :: allocator< std :: string>>到"std :: string" 上,我如何包含srand(time(NULL));而不是每次都在main上声明它们.可以将其包含在我的随机函数中吗?

I am trying to generate my key random and joining a few hyphen after the key , but however when I try to do this I got no suitable user-defined conversion from "std::vector<std::string, std::allocator<std::string>>" to "std::string" on the other hand how can I include srand(time(NULL)); instead of declaring them every time on main . is will possible to include it on my random function?

typedef unsigned int uint;

std::string randomString(uint length, std::string string){
    std::vector<uint> indexesOfRandomChars(length); // array of random values that will be used to iterate through random indexes of 'charIndex'
    for (uint i = 0; i < length; ++i) // assigns a random number to each index of "indexesOfRandomChars"
        indexesOfRandomChars[i] = rand() % string.length();

    std::string key = ""; // random string that will be returned by this function
    for (uint i = 0; i < length; ++i)// appends a random amount of random characters to "randomString"
    {
        key += string[indexesOfRandomChars[i]];
    }
    return key;
}


int main() {
    srand(time(NULL));
    std::vector<std::string> t{ reverse.ascii_lowercase() , reverse.ascii_uppercase() , reverse.digits() , reverse.punctuation() };
    std::cout << reverse.join(randomString(15, t), "--") << std::endl;
    std::cin.get();
}

推荐答案

正如注释中所建议的那样, randomString 的第二个参数是 std :: string ,但是传递 std :: vector< std :: string>t .这样就得到了当前的编译错误.例如,如果 join 的第一个参数的类型为 std :: vector< std :: string> ,则 randomString 的调用方应该如下:

As already suggested in comments, the second argument of randomString is std::string but you are passing std::vector<std::string> t to it. Thus you get the current compilation error. For instance, if the type of the first argument of join is std::vector<std::string>, the caller side of randomString should be as follows:

std::vector<std::string> t{
    randomString(15, reverse.ascii_lowercase()),
    randomString(15, reverse.ascii_uppercase()),
    randomString( 5, reverse.digits()),
    randomString( 5, reverse.punctuation()) };

std::cout << reverse.join(t, "--") << std::endl;


下一步


Next,

如何包含srand(time(NULL));而不是每次都在main上声明它们

how can I include srand(time(NULL)); instead of declaring them every time on main

在C ++中,静态局部变量的生存期始于调用函数,而终止于程序结束.因此,以下 setSeed 中的 srand(time(NULL())在运行时仅被调用一次,因此您可以包含 srand(time(NULL)),而不是在main函数中声明它们.(请注意, srand 在全球范围内有效,如果您出于其他目的在其他函数中调用 rand(),那么您还需要调用此 setSeed .然后,在这种情况下,主功能似乎是调用 srand 的最合适的点.)

In C++, the life time of static local variables starts when the function is called and ends when the program ends. Therefore, srand(time(NULL)) in the following setSeed is called only once through the run-time and in this way you can include srand(time(NULL)) in the randomString instead of declaring them in the main function. (Please note that srand is in effect globally and if you are calling rand() in other functions with different purposes then you also need to call this setSeed in these functions. Then, in this case, the main function seems to be the most appropriate point to call srand.)

实时演示

void setSeed()
{
    static bool set = false;
    
    if(!set)
    {
        srand(time(NULL));
        set = true;
    }
}

std::string randomString(uint length, std::string string)
{
    setSeed(); // I added this line.
    
    std::vector<uint> indexesOfRandomChars(length); // array of random values that will be used to iterate through random indexes of 'charIndex'
    for (uint i = 0; i < length; ++i) // assigns a random number to each index of "indexesOfRandomChars"
        indexesOfRandomChars[i] = rand() % string.length();

    std::string key = ""; // random string that will be returned by this function
    for (uint i = 0; i < length; ++i)// appends a random amount of random characters to "randomString"
    {
        key += string[indexesOfRandomChars[i]];
    }
    return key;
}


BTW,尽管通常应使用更好的LCG来实现 rand(),但是,例如,如C ++标准草案n4687中所述, rand()中使用的算法是完全由编译器实现定义的:


BTW, although rand() should be usually implemented using something better LCG, but, for instance as noted in C++ standard draft n4687, the algorithm used in rand() is completely compiler implementation defined:

29.6.9低质量随机数生成[c.math.rand]

int rand();
void srand(unsigned int seed);

... rand的基础算法未指定.因此,兰德的使用仍然是不可携带的,其质量和性能是不可预测的,而且常常是令人质疑的.

... rand’s underlying algorithm is unspecified. Use of rand therefore continues to be non-portable, with unpredictable and oft-questionable quality and performance.

幸运的是,在C ++ 11及更高版本中,我们可以使用< random> 来生成有保证的质量随机性.因此,我建议您按以下方式使用它们.在这里,我还避免了 std :: minstd_rand 的递归构造,并在

Fortunately, in C++11 and over, we can use <random> to generate a guaranteed quality randomness. Thus I recommend you to use them as follows. Here I also avoid recursive construction of std::minstd_rand and make the function thread-safe applying the accepted answer in this post. If you need more high-quality randomness, you can use std::mt19937 instead of std::minstd_rand:

实时演示

#include <random>

std::string randomString(
    std::size_t length,
    const std::string& str)
{
    static thread_local std::minstd_rand gen(std::random_device{}());
    std::uniform_int_distribution<std::size_t> dist(0, str.length()-1);
    
    std::string ret;
    ret.reserve(length);
    
    for(std::size_t i = 0; i < length; ++i){
        ret.push_back(str[dist(gen)]);
    }
    
    return ret;
}

这篇关于目前将矢量转换为字符串的密码生成器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆