如何在 C++ 中创建一个随机的字母数字字符串?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/440133/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:21:52  来源:igfitidea点击:

How do I create a random alpha-numeric string in C++?

c++stringrandom

提问by jm.

I'd like to create a random string, consisting of alpha-numeric characters. I want to be able to be specify the length of the string.

我想创建一个随机字符串,由字母数字字符组成。我希望能够指定字符串的长度。

How do I do this in C++?

我如何在 C++ 中做到这一点?

回答by Ates Goral

Mehrdad Afshari's answerwould do the trick, but I found it a bit too verbose for this simple task. Look-up tables can sometimes do wonders:

Mehrdad Afshari 的回答可以解决问题,但我发现它对于这个简单的任务来说有点过于冗长。查找表有时可以创造奇迹:

void gen_random(char *s, const int len) {
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

    for (int i = 0; i < len; ++i) {
        s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
    }

    s[len] = 0;
}

回答by Carl

Here's my adaptation of Ates Goral's answer using C++11. I've added the lambda in here, but the principle is that you could pass it in and thereby control what characters your string contains:

这是我使用 C++11 改编的 Ates Goral 的答案。我在这里添加了 lambda,但原则是您可以传入它,从而控制您的字符串包含哪些字符:

std::string random_string( size_t length )
{
    auto randchar = []() -> char
    {
        const char charset[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(length,0);
    std::generate_n( str.begin(), length, randchar );
    return str;
}

Here is an example of passing in a lambda to the random string function: http://ideone.com/Ya8EKf

这是将 lambda 传递给随机字符串函数的示例:http: //ideone.com/Ya8EKf

Why would you use C++11?

为什么要使用C++11

  1. Because you can produce strings that follow a certain probability distribution(or distribution combination) for the character set you're interested in.
  2. Because it has built-in support for non-deterministic random numbers
  3. Because it supports unicode, so you could change this to an internationalized version.
  1. 因为您可以为您感兴趣的字符集生成遵循特定概率分布(或分布组合)的字符串。
  2. 因为它内置了对非确定性随机数的支持
  3. 因为它支持unicode,所以你可以把它改成国际化的版本。

For example:

例如:

#include <iostream>
#include <vector>
#include <random>
#include <functional> //for std::function
#include <algorithm>  //for std::generate_n

typedef std::vector<char> char_array;

char_array charset()
{
    //Change this to suit
    return char_array( 
    {'0','1','2','3','4',
    '5','6','7','8','9',
    'A','B','C','D','E','F',
    'G','H','I','J','K',
    'L','M','N','O','P',
    'Q','R','S','T','U',
    'V','W','X','Y','Z',
    'a','b','c','d','e','f',
    'g','h','i','j','k',
    'l','m','n','o','p',
    'q','r','s','t','u',
    'v','w','x','y','z'
    });
};    

// given a function that generates a random character,
// return a string of the requested length
std::string random_string( size_t length, std::function<char(void)> rand_char )
{
    std::string str(length,0);
    std::generate_n( str.begin(), length, rand_char );
    return str;
}

int main()
{
    //0) create the character set.
    //   yes, you can use an array here, 
    //   but a function is cleaner and more flexible
    const auto ch_set = charset();

    //1) create a non-deterministic random number generator      
    std::default_random_engine rng(std::random_device{}());

    //2) create a random number "shaper" that will give
    //   us uniformly distributed indices into the character set
    std::uniform_int_distribution<> dist(0, ch_set.size()-1);

    //3) create a function that ties them together, to get:
    //   a non-deterministic uniform distribution from the 
    //   character set of your choice.
    auto randchar = [ ch_set,&dist,&rng ](){return ch_set[ dist(rng) ];};

    //4) set the length of the string you want and profit!        
    auto length = 5;
    std::cout<<random_string(length,randchar)<<std::endl;
    return 0;
}

Sample output.

样本输出。

回答by Galik

My 2p solution:

我的 2p 解决方案:

#include <random>
#include <string>

std::string random_string(std::string::size_type length)
{
    static auto& chrs = "0123456789"
        "abcdefghijklmnopqrstuvwxyz"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    thread_local static std::mt19937 rg{std::random_device{}()};
    thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);

    std::string s;

    s.reserve(length);

    while(length--)
        s += chrs[pick(rg)];

    return s;
}

回答by Mehrdad Afshari

 void gen_random(char *s, size_t len) {
     for (size_t i = 0; i < len; ++i) {
         int randomChar = rand()%(26+26+10);
         if (randomChar < 26)
             s[i] = 'a' + randomChar;
         else if (randomChar < 26+26)
             s[i] = 'A' + randomChar - 26;
         else
             s[i] = '0' + randomChar - 26 - 26;
     }
     s[len] = 0;
 }

回答by nly

I just tested this, it works sweet and doesn't require a lookup table. rand_alnum() sort of forces out alphanumerics but because it selects 62 out of a possible 256 chars it isn't a big deal.

我刚刚测试了这个,它工作得很好,不需要查找表。rand_alnum() 有点强制排除字母数字,但因为它从可能的 256 个字符中选择了 62 个,所以没什么大不了的。

#include <cstdlib>   // for rand()
#include <cctype>    // for isalnum()   
#include <algorithm> // for back_inserter
#include <string>

char 
rand_alnum()
{
    char c;
    while (!std::isalnum(c = static_cast<char>(std::rand())))
        ;
    return c;
}


std::string 
rand_alnum_str (std::string::size_type sz)
{
    std::string s;
    s.reserve  (sz);
    generate_n (std::back_inserter(s), sz, rand_alnum);
    return s;
}

回答by Konrad Rudolph

Rather than manually looping, prefer using the appropriate C++ algorithm, in this case std::generate_n, with a proper random number generator:

与其手动循环,不如使用适当的C++ 算法,在这种情况下std::generate_n,使用适当的随机数生成器

auto generate_random_alphanumeric_string(std::size_t len) -> std::string {
    static constexpr auto chars =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    thread_local auto rng = random_generator<>();
    auto dist = std::uniform_int_distribution{{}, std::strlen(chars) - 1};
    auto result = std::string(len, '
template <typename T = std::mt19937>
auto random_generator() -> T {
    auto constexpr seed_bits = sizeof(typename T::result_type) * T::state_size;
    auto constexpr seed_len = seed_bits / std::numeric_limits<std::seed_seq::result_type>::digits;
    auto seed = std::array<std::seed_seq::result_type, seed_len>{};
    auto dev = std::random_device{};
    std::generate_n(begin(seed), seed_len, std::ref(dev));
    auto seed_seq = std::seed_seq(begin(seed), end(seed));
    return T{seed_seq};
}
'); std::generate_n(begin(result), len, [&]() { return chars[dist(rng)]; }); return result; }

This is close to something I would call the “canonical” solution for this problem.

这接近于我称之为这个问题的“规范”解决方案。

Unfortunately, correctly seeding a generic C++ random number generator (e.g. MT19937) is really hard. The above code therefore uses a helper function template, random_generator:

不幸的是,正确地播种一个通用的 C++ 随机数生成器(例如 MT19937)真的很难。因此,上面的代码使用了一个辅助函数模板random_generator

#include <algorithm>
#include <array>
#include <cstring>
#include <functional>
#include <limits>
#include <random>
#include <string>

This is complex and relatively inefficient. Luckily it's used to initialise a thread_localvariable and is therefore only invoked once per thread.

这是复杂且相对低效的。幸运的是,它用于初始化一个thread_local变量,因此每个线程只调用一次。

Finally, the necessary includes for the above are:

最后,上述必要的包括:

#include <iostream>
#include <string>
#include <stdlib.h>     /* srand, rand */

using namespace std;

string RandomString(int len)
{
   string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
   string newstr;
   int pos;
   while(newstr.size() != len) {
    pos = ((rand() % (str.size() - 1)));
    newstr += str.substr(pos,1);
   }
   return newstr;
}

int main()
{
   srand(time(0));
   string random_str = RandomString(100);
   cout << "random_str : " << random_str << endl;
}

The above code uses class template argument deductionand thus requires C++17. It can be trivially adapted for earlier versions by adding the required template arguments.

上面的代码使用类模板参数推导,因此需要 C++17。通过添加所需的模板参数,它可以轻松适应早期版本。

回答by D D

I hope this helps someone.

我希望这可以帮助别人。

Tested at https://www.codechef.com/idewith C++ 4.9.2

https://www.codechef.com/ide 上使用 C++ 4.9.2 进行测试

void gen_random(char *s, int l) {
    for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0););
}

Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd

Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd

回答by geza

Here's a funny one-liner. Needs ASCII.

这是一个有趣的单线。需要 ASCII。

#include <iostream>
#include <string>
#include <random>

std::string generateRandomId(size_t length = 0)
{
    static const std::string allowed_chars {"123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"};

    static thread_local std::default_random_engine randomEngine(std::random_device{}());
    static thread_local std::uniform_int_distribution<int> randomDistribution(0, allowed_chars.size() - 1);

    std::string id(length ? length : 32, '
QString random_string(int length=32, QString allow_symbols=QString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")) {
    QString result;
    qsrand(QTime::currentTime().msec());
    for (int i = 0; i < length; ++i) {            
        result.append(allow_symbols.at(qrand() % (allow_symbols.length())));
    }
    return result;
}
'); for (std::string::value_type& c : id) { c = allowed_chars[randomDistribution(randomEngine)]; } return id; } int main() { std::cout << generateRandomId() << std::endl; }

回答by Oleg

##代码##

回答by Vitalja Alex

Example for Qt use:)

Qt 使用示例:)

##代码##