Me gustaría crear una cadena aleatoria, que consta de caracteres alfanuméricos. Quiero poder especificar la longitud de la cadena.
¿Cómo hago esto en C ++?
La respuesta de Mehrdad Afshari haría el truco, pero me pareció un poco demasiado detallado para esta simple tarea. Las tablas de búsqueda a veces pueden hacer maravillas:
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; }
Aquí está mi adaptación de la respuesta de Ates Goral usando C ++ 11. He agregado el lambda aquí, pero el principio es que puedes pasarlo y así controlar qué caracteres contiene tu cadena:
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; }
Aquí hay un ejemplo de cómo pasar un lambda a la función de cadena aleatoria: http://ideone.com/Ya8EKf
¿Por qué usarías C ++ 11 ?
Por ejemplo:
#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<
Muestra de salida.
Mi solución 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; }
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; }
Tiendo a utilizar siempre las formas estructuradas de C ++ para este tipo de inicialización. Tenga en cuenta que, fundamentalmente, no es diferente de la solución de Altan. Para un progtwigdor de C ++, simplemente expresa la intención un poco mejor y podría ser más fácil de transportar a otros tipos de datos. En este caso, la función C ++ generate_n
expresa exactamente lo que desea:
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';
Por cierto, lea el ensayo de Julienne sobre por qué este cálculo del índice es preferible a los métodos más simples (como tomar el módulo).
Acabo de probar esto, funciona bien y no requiere una tabla de búsqueda. rand_alnum () elimina los caracteres alfanuméricos, pero como selecciona 62 de los posibles 256 caracteres, no es un gran problema.
#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; }
Espero que esto ayude a alguien.
Probado en https://www.codechef.com/ide con C ++ 4.9.2
#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
Algo aún más simple y básico en caso de que esté contento con que su cadena contenga cualquier carácter imprimible:
#include // we'll use time for the seed #include // 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 }
Aquí hay un divertido delineador. Necesita ASCII.
void gen_random(char *s, int l) { for (int c; c=rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0);); }
Cadena aleatoria, cada archivo de ejecución = cadena diferente
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);
Ejemplo para el uso de 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 #include #include 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 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; }
#include #include template void genRandomString(char (&buffer)[N]) { std::random_device rd; const char alphanumeric[] = { "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" }; std::mt19937 eng(rd()); std::uniform_int_distribution<> distr(0, 61); for (auto& c : buffer) c = alphanumeric[distr(eng)]; buffer[N] = '\0'; } int main() { char buffer[100]; // 99 is the string length genRandomString(buffer); std::cout << buffer << '\n'; return 0; }
Sé útil cuando llames a la función
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(); }
(adaptado de @Ates Goral ) dará como resultado la misma secuencia de caracteres cada vez. Utilizar
srand(time(NULL));
antes de llamar a la función, aunque la función rand () siempre se siembra con 1 @kjfletch .
Por ejemplo:
void SerialNumberGenerator() { srand(time(NULL)); for (int i = 0; i < 5; i++) { cout << gen_random(10) << endl; } }
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'; }