it-swarm.com.de

Wie erstelle ich eine zufällige alphanumerische Zeichenfolge in C++?

Ich möchte eine zufällige Zeichenfolge erstellen, die aus alphanumerischen Zeichen besteht. Ich möchte die Länge der Zeichenfolge angeben können.

Wie mache ich das in C++?

150
jm.

Mehrdad Afshari's answer würde den Trick tun, aber ich fand es etwas zu wortreich für diese einfache Aufgabe. Nachschlagetabellen können manchmal Wunder bewirken:

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;
}
252
Ates Goral

Hier ist meine Anpassung von Ates Goral mit C++ 11. Ich habe das Lambda hier hinzugefügt, aber das Prinzip ist, dass Sie es weitergeben und damit kontrollieren können, welche Zeichen Ihre Zeichenfolge enthält:

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

Hier ist ein Beispiel für die Übergabe eines Lambda an die Zufallsstringfunktion: http://ideone.com/Ya8EKf

Warum sollten Sie C++ 11 verwenden? 

  1. Sie können Strings erzeugen, die einer bestimmten Wahrscheinlichkeitsverteilung (oder Verteilungskombination) für den gewünschten Zeichensatz entsprechen.
  2. Weil es eine integrierte Unterstützung für nicht deterministische Zufallszahlen hat
  3. Da es Unicode unterstützt, können Sie dies in eine internationalisierte Version ändern.

Zum Beispiel:

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

Beispielausgabe.

89
Carl

Meine 2p-Lösung:

#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;
}
26
Galik
 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;
 }
15
Mehrdad Afshari

Ich habe es gerade getestet, es funktioniert gut und erfordert keine Nachschlagetabelle. Rand_alnum () zwingt alphanumerische Zeichen heraus, aber da es 62 von möglichen 256 Zeichen auswählt, ist das keine große Sache.

#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;
}
8
nly

Ich neige dazu, für diese Art der Initialisierung immer die strukturierten C++ - Methoden zu verwenden. Beachten Sie, dass es grundsätzlich nicht anders ist als die Lösung von Altan. Für einen C++ - Programmierer drückt es einfach die Absicht etwas besser aus und ist möglicherweise leichter auf andere Datentypen portierbar. In diesem Fall drückt die C++ - Funktion generate_n genau das aus, was Sie möchten:

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

Übrigens, lesen Sie Juliennes Essay , warum diese Berechnung des Index gegenüber einfacheren Methoden (wie dem Modul) bevorzugt wird.

8
Konrad Rudolph

Ich hoffe das hilft jemandem.

Getestet unter https://www.codechef.com/ide mit 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

7
D D

Hier ist ein lustiger Einzeiler. Benötigt ASCII.

void gen_random(char *s, int l) {
    for (int c; c=Rand()%62, *s++ = (c+"07="[(c+16)/26])*(l-->0););
}
3
geza
#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;
}
2
Hazey

Beispiel für die Verwendung von 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;
}
1
Vitalja Alex

Zufällige Zeichenfolge, jede Laufdatei = andere Zeichenfolge

        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);
1
Nehigienix
#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, '\0');

    for (std::string::value_type& c : id) {
        c = allowed_chars[randomDistribution(randomEngine)];
    }

    return id;
}

int main()
{
    std::cout << generateRandomId() << std::endl;
}
1
Oleg

Noch einfacher und grundlegender für den Fall, dass Sie froh sind, dass Ihre Zeichenfolge druckbare Zeichen enthält:

#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
}
1
Nobilis
#include <iostream>
#include <string>
#include <stdlib.h>
int main()
{
    int size;
    std::cout << "Enter size : ";
    std::cin >> size;
    std::string str;
    for (int i = 0; i < size; i++)
    {
        auto d = Rand() % 26 + 'a';
        str.Push_back(d);
    }
    for (int i = 0; i < size; i++)
    {
        std::cout << str[i] << '\t';
    }

    return 0;
}
0
ras

Lass uns wieder zufällig bequem machen!

Ich habe eine Nice C++ 11-Header-Lösung entwickelt, die nur aus einem Header besteht. Sie könnten problemlos eine Header-Datei zu Ihrem Projekt hinzufügen und dann Ihre Tests hinzufügen oder zufällige Zeichenfolgen für andere Zwecke verwenden.

Dies ist eine kurze Beschreibung, aber Sie können dem Link folgen, um den vollständigen Code zu überprüfen. Der Hauptteil der Lösung ist in der Klasse Randomer:

class Randomer {
    // random seed by default
    std::mt19937 gen_;
    std::uniform_int_distribution<size_t> dist_;

public:
    /* ... some convenience ctors ... */

    Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
        : gen_{seed}, dist_{min, max} {
    }

    // if you want predictable numbers
    void SetSeed(unsigned int seed) {
        gen_.seed(seed);
    }

    size_t operator()() {
        return dist_(gen_);
    }
};

Randomer enthält alle zufälligen Elemente und Sie können ganz einfach Ihre eigenen Funktionen hinzufügen. Nachdem wir Randomer haben, ist es sehr einfach, Strings zu generieren:

std::string GenerateString(size_t len) {
    std::string str;
    auto Rand_char = [](){ return alphabet[randomer()]; };
    std::generate_n(std::back_inserter(str), len, Rand_char);
    return str;
}

Schreiben Sie unten Ihre Verbesserungsvorschläge. https://Gist.github.com/VjGusev/e6da2cb4d4b0b531c1d009cd1f8904ad

0
Gusev Slava