7
votes

Semagne à plusieurs reprises un générateur de nombres aléatoires une fonction de hachage raisonnable?

Je souhaite générer une grande quantité de données aléatoires, qui est reproductible pour une clé donnée , comprenant une liste de nombres: xxx

est le suivant un moyen bon ou raisonnable d'obtenir une RNG dans un état pour générer des données aléatoires, de telle manière que pour chaque N-tuple [A, B, C, ..., N] , ces données sont non corrélé avec la sortie pour les N-tuples "adjacents" [A + 1, B, C, ..., N] , [A, B + 1, C, ... , n] , etc. xxx

Je pense que cette question revient à ce qui suit: est rand_hash une bonne fonction de hachage pour le 2-tuple (A, b) ? xxx

nb: je ne souhaite pas impliquer que srand et rand est une implémentation particulière d'une RNG. Supposez-vous pour des arguments que nous utilisons un bon code Twister Mersenne.

edit : S'il n'est pas clair, par "Fonction de hachage raisonnable", je veux dire ce qui suit . Dans le cas restreint d'un 2-tuple [A, B] , la sortie de rand_hash doit être uniforme sur la plage de int , et (typiquement) il ne devrait y avoir aucune corrélation entre la magnitude dans le changement de A ou B et la magnitude de la modification de la valeur de retour.


15 commentaires

Comment définissez-vous la «Fonction de hachage raisonnable»? Que faites-vous avec le code de hachage?


Srand (A ^ b ^ c ^ ... ^ n) est plus rapide que ce que vous avez, et tout aussi efficace.


Supposons n est zéro. Ensuite (si srand définit complètement l'état du générateur) La sortie est indépendante de tous les blocs précédents.


@MOOINGDUCK Non, c'est inutile si nous discutons des tuples, car la sortie pour A = 3, B = 2 devrait être différente de A = 2, B = 3.


@MOOINGDUCK: Non, ce n'est pas vrai. Voir blogs.msdn .COM / B / ERICLIPPERT / Archive / 2011/02/28 / ... - Faites défiler jusqu'à «En particulier, faites attention à« XOR ».


@Nick: Pourquoi ces sorties devraient-elles être différentes? Nous parlons d'une fonction de hachage ici. Les doublons sont autorisés. (Évidemment, votre ensemble d'entrées possibles est deux fois l'ensemble des sorties possibles, il y a donc un chevauchement quelque part)


Nick: votre origion a le même problème, mais je vois votre point. @Billy: Je n'ai jamais entendu ça avant. Bon à savoir.


@MOOINGDUCK Mon commentaire a été dirigé vers le code dans la question, pas à votre commentaire.


@ Paŭloebermann c'est un point valide. On pourrait simplement faire srand (rand () + x) pour éviter ce problème, cependant, non?


@Billyonéal La question est étiquetée avec [cryptographie], alors je suppose que nous voulons une fonction de hachage où il est difficile de trouver des doublons. Il suffit de xoriser les entrées ne correspond pas à la facture.


@MOOINGDUCK Le code i Publié est pas symétrique sur A et B .


@Nick: Oui, avec + (ou xor ou - ) c'est mieux. Je ne ferais toujours pas confiance à cette construction sans savoir ce que rand et srand vraiment (ou au moins avoir des propriétés assurées pour eux).


@Nick: Il peut être symétrique pour une implémentation de rand .


@ Paŭloebermann: J'ai dit «Supposons pour l'argument selon lequel nous utilisons un bon code Twister Mersenne» ...


@NICK: La plupart des implément des rand n'utilisent pas d'algorithmes aussi bien que Mersenne Twister. Vous avez de la chance d'obtenir un bon générateur de congulations linéaires. C RAND n'est pas conçu pour les applications cryptographiques graves.


3 Réponses :


2
votes

Qu'en est-il d'utiliser boost :: hash_commine http://www.boost.org/doc/libs/1_33_1/doc/html/hash_commine.html Pour créer votre graine initiale? En utilisant srand plus d'une fois déclenche toujours des drapeaux rouges dans mon esprit.


1 commentaires

et std :: hash pour les valeurs initiales. Bonne idée.



1
votes

Problème potentiel:

Et si un autre fil appelle rand () au milieu de votre fonction de hachage?


1 commentaires

C'est un point juste, mais nous pouvons supposer que la minute où les problèmes de threading ne sont pas pertinents ici. Dans la pratique, j'utilise un RNG instancié de C ++ 11 .



10
votes

Non, ce n'est pas une approche raisonnable.

  1. Vous ne savez pas quelle est la mise en œuvre de rand code> est. Les générateurs de nombres aléatoires sont conçus pour fournir des nombres approximativement distribués sur une période de plusieurs mnumbers générés. Ils ne sont pas conçus pour fournir des nombres uniformément distribués sur l'ensemble des graines (32 bits). Dans votre cas hypothétique MERSENNE_TWISTER CODE>, le générateur de nombres aléatoires a un état beaucoup plus grand que l'entier que vous fournissez à srand code> (spécifiquement, 624 * Taille de (int) code >). La majeure partie de la puissance doit s'assurer que sa production est aléatoire et uniforme de cet état supplémentaire et vous avez pris cela. (La graine ne peut être que l'un des 2 ^ 32 états) li>
  2. Si vous améliorez jamais votre compilateur ou votre bibliothèque ou quelque chose de similaire, tout ce que vous pourriez avoir sérialisé sur disque deviendra illisible. (Si rand code> est une boîte noire, personne ne dit que la mise en œuvre de demain correspond à l'aujourd'hui). Li>
  3. La sortie de votre fonction de hachage renvoie la même chose pour les mêmes entrées sur SRAND code>. Par conséquent, vous avez déjà un hash - l'entrée à srand code>. Le RNG génère la même sortie pour une entrée donnée à srand code>. Par conséquent, le nombre de hachages que vous pouvez obtenir n'est pas plus important que de simplement retourner le hachage que vous auriez déjà calculé. Si votre hachage initial dans Srand est de mauvaise distribution pour une table de hachage, puis à l'échelle du hachage de manière appropriée de telle sorte qu'il fonctionne bien dans votre table. Li>
  4. pour certaines implémentations de rand code>, cela fonctionne extrêmement mal. Considérons un Confonctionnement linéaire générateur (qui est plus courant avec les bibliothèques C, car il a l'état de Tailleof (int) code> - par exemple le générateur BSD ). Un LCG suit le formulaire xnsext = a * xcurrent + b code>. Considérer: p>

    static int seed = 0;
    
    void srand(int newSeed)
    {
        seed = newSeed;
    }
    
    int rand()
    {
        seed = (int) ((1103515245 * ((unsigned int)seed) + 12345) & 0x7fffffffUL); 
        return seed;
    }
    


14 commentaires

Je ne comprends pas le point 3. Comment puis-je combiner un tuple d'entiers en un seul argument à Srand () de telle manière que leur commande est importante?


Je ne suivez pas le point n ° 3. Vous semblez dire que son hachage est un hachage et que cela fonctionne comme il a l'intention.


@Nick: multipliez-les par différentes valeurs (constantes), comme les pouvoirs de deux?


@Nick: retour gauche ^ (droite + 1) ? Je ne suis pas sûr de ce qu'un bon hash serait pour vous. Comme toujours, un bon hachage dépend de la répartition des probabilités de vos données. (Et en outre, c'est une question distincte) considérer Stackoverflow.com/search?q=commine+hash+codeses


@MOOINGDUCK: # 3 dit qu'il n'obtient rien en traversant les mouvements de Rand et Srand. Bien sûr, les chiffres que vous obtenez sont différents. La distribution du hachage que vous obtenez est différente, bien sûr, mais à travers Rand ne rend pas le hasch "mieux" en termes de "force" du hachage (au moins pas de manière bien définie).


@Billyonéal: Oh, à droite. Ouais, ça a du sens maintenant. Je connaissais déjà la Tidbit, je n'ai tout simplement pas compris son libellé.


@Billyonéal, je suis toujours perplexe par # 3. Vous parlez de «mieux» et de «différent» dans votre commentaire ci-dessus, mais mieux que quoi? Différent de quoi? Il n'a pas présenté une méthode de hachage alternative et non plus, alors je ne sais pas ce que vous comparez.


@Nick: Je ne sais pas ce que c'est sa méthode de hachage. Il a évidemment eu les chiffres qu'il met à srand de quelque part ...


@Billyonéal J'ai supposé qu'ils ne sont pas du tout un hachage, mais plutôt les données réelles qu'il dépend de.


@Nick: Il n'y a pas de différence. Si vos données sont suffisamment distribuées, cela fonctionne comme un hachage, il fonctionne comme un hachage. Sans rien savoir sur les données utilisées, il n'y a aucun moyen d'écrire un hachage mieux que d'utiliser l'utilisation du Int en tant que hachage.


@Billyonéal mais il n'a rien dit de la manière dont son entrée a été distribuée. C'est aussi un ensemble d'entiers, pas un seul entier.


@Nick: Mais chaque entier peut être interprété comme un hachage. Après tout, un RNG valide pourrait renvoyer sa graine comme le premier nombre généré, puis cela dégénère dans INT1 * INT2. Vous ne pouvez pas faire d'arguments sur la distribution du hachage résultant, car A. Vous ne connaissez pas la distribution de l'entrée, et B. Vous ne connaissez pas la mise en œuvre de RAND. Même si vous supposez la mise en œuvre la plus courante de RAND (un LCG), la sortie a la même distribution que l'entrée pour la plupart des ensembles d'entrée.


@Billyonéal Assurez-vous que vous pouvez traiter chaque entier comme un hash - mais l'OP spécifiquement interrogé sur la façon de semer un PRNG basé sur une tuple, et simplement dire que «chaque élément pourrait être traité comme un hash» ne vous aide pas. Traiter chaque élément en tant que hachage, peut également donner une très mauvaise distribution en fonction de ce que sont les chiffres. Et je ne faisais aucun argument sur la distribution d'un hachage basé sur le PRNG, juste que votre point 3 semble faire référence à une fonction de hachage que personne n'a spécifié ou même indiqué n'existe.


@Nick: Le point est cependant, en cours d'exécution à travers le RNG ne change pas la distribution des chiffres. La force de votre hachage n'est donc pas meilleure que les chiffres que vous y parvenez.