12
votes

Comment générez-vous des chaînes aléatoires en C ++?

Je cherche des méthodes pour générer des chaînes aléatoires en C ++. Voici mon code: xxx

mais la graine (heure (null)) n'est pas aléatoire Assez. Il y a un autre meilleur moyen de générer des chaînes aléatoires en C ++?


3 commentaires

Pourriez-vous s'il vous plaît expliquer «pas assez aléatoire»?


@Bobby: C'est parce que ma mauvaise utilisation du stand que la chaîne aléatoire produite serait la même si vous appelez la fonction dans un intervalle de temps court.


"Pas assez aléatoire" - alors vous pouvez dormir (1) par ex. . Mais naturellement, c'est une très mauvaise idée, car évidemment, vous ne pouvez pas attendre trop longtemps. mais néanmoins c'est toujours une idée


6 Réponses :


25
votes

n'appelle pas srand () sur chaque appel de fonction - appelez-le uniquement une fois au premier appel à la fonction ou au démarrage du programme. Vous voulez avoir un drapeau indiquant si srand () a déjà été appelé.

La méthode suged est bonne sauf que vous utilisez mal srand () et obtenez des résultats prévisibles des mauvais résultats.


4 commentaires

+1 Excellente réponse. Un problème avec un tel drapeau est qu'une autre fonction nécessitant des nombres aléatoires, mais en utilisant un drapeau différent, entraînera également des problèmes. Je pense que c'est mieux si les fonctions nécessitant des numéros aléatoires ne sont que des nombres aléatoires et sont découplés à partir de l'initialisation du générateur. Vraiment, l'ensemencement devrait simplement être fait en haut de principal . :-)


Ou utilisez les versions de re-entrant avec leur propre graine


@FA: True, qui empêche les générateurs de se lancer sur l'autre, mais si ces différentes fonctions sont toutes initialement exécutées de trop près ensemble, vous rencontrez toujours le même problème.


La réutilisation des valeurs de semences est une mauvaise idée. Si vous devez construire votre propre fonction RAND qui appelle Srand () la première fois (renvoyer le résultat de Rand ()).



1
votes

Vous pouvez utiliser Boost.Random . Il utilise un générateur différent de celui fourni avec la plupart des bibliothèques standard qui doivent être plus robustes.

Dans des bibliothèques spécifiques spécifiques, la plupart des bibliothèques standard fournissent des générateurs congruentiels linéaires, qui ne fonctionnent pas très bien lorsque vous MOD leurs résultats avec de petits nombres. Boost.random a un générateur Twister Mersenne.

Comme Sharmpooth dit, bien que (bonne tache!), Seulement semer le générateur une fois, au début de votre programme. L'ensemencement à chaque fois que vous voulez quelque chose de hasard est contre-productif.


2 commentaires

Non seulement l'ensemencement sur chaque appel est contre-productif, mais si la fonction est appelée à plusieurs reprises sans un retard suffisamment long, il produira des résultats identiques.


Exactement. Vraiment, il serait préférable que les bibliothèques fassent ce que Perl fait à cet égard et que l'initialisation elle-même (avec une graine sensible bien sûr) si le programme lui-même n'a pas fait. Je veux dire, il est trop tard pour cela maintenant, dans cette norme C Bibliothèques C ne pouvait pas le faire sans violer la norme, mais vous savez ce que je veux dire. :-)



1
votes

Faites une interface pour obtenir un numéro aléatoire dans ce site http://www.random.org/ Et vous serez sûr d'obtenir un vrai nombre aléatoire! Mais si vous recherchez des performances ...


0 commentaires

0
votes

sur des systèmes UNIX Vous pouvez lire des valeurs aléatoires dans le fichier / dev / aléatoire


1 commentaires

Sauf si vous utilisez les chiffres à des fins cryptographiques, lisez directement / dev / aléatoire (sauf à utiliser comme une graine à un autre PRNG) est inutile.



0
votes

Si vous préférez utiliser la bibliothèque standard, vous pouvez faire quelque chose comme ceci:

<somewhere else>
srand(NULL);
</somewhere else>

char get_rand_char() {
  static string charset(...);
  return charset[rand() % charset.size()];
}

std::string generate_random_string(size_t n) {
  char rbuf[n];
  std::generate(rbuf, rbuf+n, &get_rand_char);
  return std::string(rbuf, n);
}


0 commentaires

1
votes

utiliser std :: générate_n. De cette façon, vous pouvez spécifier la longueur de votre chaîne générée. Dans le cas ci-dessous, c'est 4.

std::string uniqueName() {
    auto randchar = []() -> char
    {
        const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        const size_t max_index = (sizeof(charset) - 1);
        return charset[ rand() % max_index ];
    };
    std::string str(4,0);
    std::generate_n( str.begin(), 4, randchar );
    return str;
}


0 commentaires