Je comprends que la spécification C ne donne aucune spécification sur l'implémentation spécifique de rand()
. Quels algorithmes différents sont couramment utilisés sur différentes plateformes majeures? En quoi diffèrent-ils?Quels sont les algorithmes courants utilisés pour rand() de C?
Répondre
Voir cet article: http://en.wikipedia.org/wiki/List_of_random_number_generators
Voici le code source de rand()
de glibc:
/* Reentrant random function from POSIX.1c.
Copyright (C) 1996, 1999, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <[email protected]>, 1996.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdlib.h>
/* This algorithm is mentioned in the ISO C standard, here extended
for 32 bits. */
int
rand_r (unsigned int *seed)
{
unsigned int next = *seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int) (next/65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next/65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next/65536) % 1024;
*seed = next;
return result;
}
Source: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/rand_r.c;hb=HEAD
Comme vous pouvez le voir, il est multiplier simplement avec un ajout et un changement . Les valeurs sont soigneusement choisies pour s'assurer que vous n'obtenez pas de répétition de la sortie pour les itérations RAND_MAX.
Notez que c'est une ancienne mise en œuvre qui a été remplacé par un algorithme plus complexe: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=HEAD
Si le lien si elle est brisée, Google pour « glibc rand_r »
C'est tout? Étonnamment simple. Merci beaucoup. – Jetbeard
Oui, c'est ça, la plupart des PNRG à usage général sont étonnamment simples à mettre en œuvre. Si vous cherchez quelque chose de plus complexe, essayez le Twister Mersenne. –
Même MT19937 n'est pas vraiment difficile à mettre en œuvre. – Joey
Vous pouvez utiliser Boost bibliothèque aléatoire pour différents générateurs de nombres aléatoires, si vous avez besoin de quelque chose de spécifique, ou plus avancé.
La documentation de Boost Random est here.
Le domaine des PRNG (Pseudo Random Number Generators) est assez vaste. Tout d'abord, vous devez comprendre que sans avoir une entrée externe (généralement physique) vous ne pouvez pas obtenir une vraie source de nombres aléatoires .. C'est pourquoi ces algorithmes sont appelés pseudo aléatoire: ils utilisent généralement une graine pour initialiser une position dans une très longue séquence que semble aléatoire mais ce n'est pas aléatoire du tout.
L'un des plus simples algorithmes est le linéaire Congruential Générateur (LCG), qui a des costraints pour garantir une longue séquence et il est sûr pas du tout. Le Blum Blum Shub Generator (BBS) est également amusant (du moins pour le nom), ce qui est inhabituel pour les PRNG normales car il repose sur l'exponentiation en modulo arithmétique, offrant une sécurité comparable à celle d'autres algorithmes comme RSA et El Gamal. briser la séquence (même si je ne suis pas sûr de la preuve)
J'ai déjà écrit un rapport sur les CRNG pour un cours en mathématiques discrètes. Pour cela, je démonte rand() dans msvcrt.dll:
msvcrt.dll:77C271D8 mov ecx, [eax+14h]
msvcrt.dll:77C271DB imul ecx, 343FDh
msvcrt.dll:77C271E1 add ecx, 269EC3h
msvcrt.dll:77C271E7 mov [eax+14h], ecx
msvcrt.dll:77C271EA mov eax, ecx
msvcrt.dll:77C271EC shr eax, 10h
msvcrt.dll:77C271EF and eax, 7FFFh
Il est donc quelque chose comme LCG (non testé) ...
int ms_rand(int& seed)
{
seed = seed*0x343fd+0x269EC3; // a=214013, b=2531011
return (seed >> 0x10) & 0x7FFF;
}
Le code source C pour la bibliothèque Microsoft C Run-time est disponible dans le cadre de MSDN, et rand()/srand() y est inclus. Voir par exemple l'implémentation portable de microsoft_rand ici: https://bitbucket.org/shlomif/fc-solve/src/dd80a812e8b3aba98a014d939ed77eb1ce764e04/fc-solve/source/board_gen/pi_make_microsoft_freecell_board.c?at=master (URL courte - http://is.gd/kAUmHW. –
- 1. Quels sont les algorithmes utilisés par les SGBDR?
- 2. Quels sont les algorithmes d'ordonnancement utilisés par le noyau Linux?
- 3. Quels sont les usages courants des bitarrays?
- 4. Où sont utilisés les algorithmes de gestion de la mémoire?
- 5. Quels sont les surnoms des caractères spéciaux de programmation courants?
- 6. Performance GPU vs CPU pour les algorithmes courants
- 7. Quels modèles de conception sont sous-utilisés?
- 8. Quels sont les types de chaînes les plus utilisés en C++ et comment les convertir?
- 9. Quels types de contrôles sont utilisés dans Windows Security Center?
- 10. Quels sont les programmes RoR utilisés dans ce tutoriel?
- 11. Des algorithmes courants pour l'indexation/la recherche dans mes données?
- 12. Quels sont les contrôles de flux les plus fréquemment utilisés pour gérer la communication de protocole?
- 13. Motifs de conception: quels sont les nouveaux, où sont utilisés les modèles existants?
- 14. Quels sont les noms de méthodes/variables/classes les plus courants que vous utilisez?
- 15. Quels sont les types de fichiers viraux les plus courants en circulation?
- 16. Quels sont les membres non-modèles C++ utilisés dans l'astuce Barton-Nackman?
- 17. C# comparer les algorithmes
- 18. Quels sont les symbos #if prédéfinis C#?
- 19. Quels sont les codes de balayage pour:
- 20. Quels algorithmes les serveurs DNS utilisent-ils pour des recherches plus rapides?
- 21. Quels garbage collectors sont disponibles pour C++?
- 22. Quels sont les objets IB utilisés dans le carnet d'adresses de Mac OS X?
- 23. Quels sont les attributs?
- 24. Quels sont les plugins recommandés pour Trac?
- 25. Quels sont les CMS pour mobile?
- 26. Quels sont les modèles de conception utilisés dans le framework Struts 1.x?
- 27. Quels sont les conseils de débogage Objective-c?
- 28. Quels sont les équivalents C# de Java getClass(), isAssignableFrom(), etc.?
- 29. Programmation fonctionnelle pour les algorithmes de base
- 30. Quels sont les modèles pour les schémas de table DB?
Le commentaire principal est que rand() est seulement pseudo- aléatoire, et souvent même pas un très bon générateur pseudo-aléatoire. La norme C suggère une implémentation possible, et de nombreuses implémentations l'utilisent. Comme d'autres l'ont noté, il y en a beaucoup d'autres. Assurez-vous simplement que vous n'utilisez pas les fonctions aléatoires de base pour les situations où vous avez besoin d'un caractère aléatoire cryptographique. –