randomize - ¿Cómo creo una cadena alfanumérica aleatoria en C++?
randomize en c (15)
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 ++?
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 <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;
}
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 <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
}
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 ?
- Porque puede producir cadenas que siguen una cierta distribución de probabilidad (o combinación de distribución) para el conjunto de caracteres que le interesan.
- Porque tiene soporte integrado para números aleatorios no deterministas
- Porque admite Unicode, por lo que podría cambiar esto a una versión internacionalizada.
Por ejemplo:
#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;
}
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;
}
Espero que esto ayude a alguien.
Probado en https://www.codechef.com/ide con C ++ 4.9.2
#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
La answer 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;
}
Mi solución 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;
}
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;
}
}
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 programador 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::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'';
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).
#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;
}
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;
}
#include <random>
#include <iostream>
template<size_t N>
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;
}
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'';
}