当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何在C++中创建随机字母数字字符串?》经验,为你挑选了7个好方法。

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

我如何在C++中执行此操作?



1> Ates Goral..:

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;
}


请使用C++ 11或随机增强,我们现在在2016年
您可能不希望使用带模数的简单rand().请参阅:http://c-faq.com/lib/randrange.html
我们需要一种方法来在stackoverflow上下沉过时的答案.
@Kent:这就是OpenSSL团队所做的,直到有人想通过valgrind来实现他们的代码.;-)
我认为`s [len] = 0`这行不正确.如果`s`是一个C字符串(NULL终止),那么该方法的签名就不必具有`len`parameter.Imo,如果你将长度作为参数传递,你假设数组不是C字符串.因此,如果你没有将C字符串传递给函数,则行[s] [len] = 0`可能会破坏事物,因为数组将从0变为len-1.即使你将C字符串传递给函数,行[s] [len] = 0`也是多余的.
此代码可能很危险,因为通常使用"len"等参数的函数会在其计数中包含终止NULL.但是这个函数实际上将len + 1个字符写入输出字符串.因此你必须小心使用它,因为如果你有`char buffer [16];`你实际上调用`gen_random(buffer,sizeof(buffer) - 1);`要特别注意记住` - 1`

2> Carl..:

这是我使用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;
}

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

为什么要使用C++ 11

    因为您可以为您感兴趣的字符集生成遵循特定概率分布(或分布组合)的字符串.

    因为它内置了对非确定性随机数的支持

    因为它支持unicode,所以您可以将其更改为国际化版本.

例如:

#include 
#include 
#include 
#include  //for std::function
#include   //for std::generate_n

typedef std::vector 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 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<

样本输出.


如果您使用的是C++ 11,那么在您的第一个代码片段中不使用`rand()`是不是更好?
我认为使用`rand()`不再是正确的.大声喊叫甚至都不统一......

3> Galik..:

我的2p解决方案:

#include 
#include 

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 pick(0, sizeof(chrs) - 2);

    std::string s;

    s.reserve(length);

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

    return s;
}



4> Mehrdad Afsh..:
 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;
 }


@dmckee:是的,但那些其他字符集是什么?(EBCDIC没有连续的字母).
但是,0..9必须是连续的。没有部门号,但是我对此很确定。

5> nly..:

我刚试过这个,它很好用,不需要查找表.rand_alnum()有点强制使用字母数字,但因为它从可能的256个字符中选择了62个,这不是什么大问题.

#include    // for rand()
#include     // for isalnum()   
#include  // for back_inserter
#include 

char 
rand_alnum()
{
    char c;
    while (!std::isalnum(c = static_cast(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;
}


无法知道此功能需要运行多长时间.这是不太可能的,但严格来说,这可能会无限期地运行.

6> Konrad Rudol..:

我倾向于总是使用结构化的C++方法进行这种初始化.请注意,从根本上说,它与Altan的解决方案没有什么不同.对于C++程序员来说,它只是表达了更好的意图,并且可以更容易地移植到其他数据类型.在这个例子中,C++函数generate_n完全表达了你想要的:

struct rnd_gen {
    rnd_gen(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789")
        : range(range), len(std::strlen(range)) { }

    char operator ()() const {
        return range[static_cast(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * len)];
    }
private:
    char const* range;
    std::size_t len;
};

std::generate_n(s, len, rnd_gen());
s[len] = '\0';

顺便说一下,请阅读Julienne的文章,了解为什么这个指数的计算比简单的方法(如取模数)更受欢迎.



7> D D..:

我希望这可以帮助别人.

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

#include 
#include 
#include      /* srand, rand */

using namespace std;

string RandomString(int len)
{
   srand(time(0));
   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()
{
   string random_str = RandomString(100);
   cout << "random_str : " << random_str << endl;
}

Output: random_str : DNAT1LAmbJYO0GvVo4LGqYpNcyK3eZ6t0IN3dYpHtRfwheSYipoZOf04gK7OwFIwXg2BHsSBMB84rceaTTCtBC0uZ8JWPdVxKXBd


加1,减1:读者,小心:`RandomString(100)`!;-)
推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有