如何在C ++中创build一个随机字母数字string?
我想创build一个随机string,由字母数字字符组成。 我希望能够指定string的长度。
我如何在C ++中做到这一点?
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改编的Ates Goral的答案。 我在这里添加了lambda,但是原理是你可以通过它来控制你的string包含的字符:
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传递给随机string函数的示例: http : //ideone.com/Ya8EKf
你为什么要用C ++ 11 ?
- 因为您可以为您感兴趣的字符集生成遵循特定概率分布 (或分布组合)的string。
- 因为它内置了对非确定性随机数的支持
- 因为它支持unicode,所以你可以把它改成一个国际化的版本。
例如:
#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; }
示例输出。
我的2p解决scheme:
#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; }
void gen_random(char *s, const int len) { for (int 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; }
我倾向于总是使用结构化的C ++方式进行这种初始化。 注意,从根本上说,它与俺答的解决scheme没有什么不同。 对于C ++程序员来说,它只是expression了更好的意图,并可能更容易移植到其他数据types。 在这个例子中,C ++函数generate_n
expression了你想要的:
struct rnd_gen { rnd_gen(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789") : range(range), len(std::strlen(range)) { } char operator ()() const { return range[static_cast<std::size_t>(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关于为什么这个指数的计算比较简单的方法(如取模数)更好的文章 。
我只是testing这个,它工作甜,不需要查找表。 rand_alnum()sorting的字母数字,但因为它从256个字符中select62,这不是什么大不了的事情。
#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; }
我希望这可以帮助别人。
用C ++ 4.9.2testinghttps://www.codechef.com/ide
#include <iostream> #include <string> #include <stdlib.h> /* 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
有些东西甚至更简单,更基本,以防您对包含任何可打印字符的string感到满意:
#include <time.h> // we'll use time for the seed #include <string.h> // this is for strcpy void randomString(int size, char* output) // pass the destination size and the destination itself { srand(time(NULL)); // seed with time char src[size]; size = rand() % size; // this randomises the size (optional) src[size] = '\0'; // start with the end of the string... // ...and work your way backwards while(--size > -1) src[size] = (rand() % 94) + 32; // generate a string ranging from the space character to ~ (tilde) strcpy(output, src); // store the random string }
随机string,每个运行文件=不同的string
auto randchar = []() -> char { const char charset[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; const size_t max_index = (sizeof(charset) - 1); return charset[randomGenerator(0, max_index)]; }; std::string custom_string; size_t LENGTH_NAME = 6 // length of name generate_n(custom_string.begin(), LENGTH_NAME, randchar);
这是一个有趣的单线。 需要ASCII。
void gen_random(char *s, int l) { for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0);); }
Qt使用示例:)
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; }
#include <iostream> #include <string> #include <random> std::string generateRandomId(size_t length = 0) { static const std::string::value_type allowed_chars[] {"123456789BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"}; static thread_local std::default_random_engine randomEngine(std::random_device{}()); static thread_local std::uniform_int_distribution<int> randomDistribution(0, sizeof(allowed_chars) - 1); std::string id(length ? length : 32, '\0'); for (std::string::value_type& c : id) { c = allowed_chars[randomDistribution(randomEngine)]; } return id; } int main() { std::cout << generateRandomId() << std::endl; }
这是我的解决scheme,我创build了testingsortingalgorithm。 它仅限于字母字符,但可以将其扩展为包含数字字符。 参数范围告诉生成器您的string的最大长度; 由于我的实现的性质(我打算这样做)),您将获得长度在区间[1; range + 1]中的string(请参阅size_t长度)。
注意:您可能要考虑转储C rand()并使用C ++随机库,因为第二个库中有许多您可以尝试的生成器,整体分布和范围比cstdlib中的rand()要好得多。 如果你正在使用rand(),在调用你的rand()之前不要忘记调用srand(SOME_SEED)。 否则,你将会得到相同的“随机”值。 :d
std::string randstr(size_t range) { size_t length = rand() % range + 1; char str[length]; str[length-1] = '\0'; size_t i = 0; int r; for(i = 0; i < length-1; ++i) { //length-1 for the '\0' at the end for(;;) { r = rand() % 57 + 65; //interval between 65 ('A') and 65+57=122 ('z') if((r >= 65 && r <= 90) || (r >= 97 && r <= 122)) { // exclude all characters between '[' and '`'; you can add numerical characters here as an interval of ASCII code the same way I did that with the alphabetic characters str[i] = (char)r; break; } } } return std::string(str); }
void strGetRandomAlphaNum(char *sStr, unsigned int iLen) { char Syms[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; unsigned int Ind = 0; srand(time(NULL) + rand()); while(Ind < iLen) { sStr[Ind++] = Syms[rand()%62]; } sStr[iLen] = '\0'; }
在调用函数时需要保存
string gen_random(const int len) { static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; stringstream ss; for (int i = 0; i < len; ++i) { ss << alphanum[rand() % (sizeof(alphanum) - 1)]; } return ss.str(); }
(由@Ates Goral改编)每次都会产生相同的字符序列。 使用
srand(time(NULL));
在调用函数之前,虽然rand()函数总是用1 @kjfletch播种 。
例如:
void SerialNumberGenerator() { srand(time(NULL)); for (int i = 0; i < 5; i++) { cout << gen_random(10) << endl; } }