Comprendo che la specifica C non fornisce alcuna specifica sull'implementazione specifica di rand()
. Quali diversi algoritmi sono comunemente usati su diverse piattaforme principali? Come si differenziano?Quali algoritmi comuni sono usati per C's rand()?
risposta
veda questo articolo: http://en.wikipedia.org/wiki/List_of_random_number_generators
Questo è il codice sorgente di di glibc rand()
:
/* 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;
}
Fonte: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/rand_r.c;hb=HEAD
Come si può vedere, è semplicemente moltiplicare con l'aggiunta e uno spostamento . I valori sono scelti con cura per assicurarsi di non avere ripetizioni dell'output per le iterazioni RAND_MAX.
Si noti che questo è un vecchio di attuazione che è stato sostituito da un algoritmo più complesso: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=HEAD
Se il collegamento in caso di rottura, Google per "glibc rand_r"
Questo è tutto? Sorprendentemente semplice. Grazie mille. – Jetbeard
Sì, questo è tutto, i PNRG più generici sono sorprendentemente semplici da implementare. Se stai cercando qualcosa di più complesso, prova il Mersenne Twister. –
Anche l'MT19937 non è esattamente difficile da implementare. – Joey
Si potrebbe utilizzare Boost biblioteca casuale per diverso generatori di numeri casuali, se hai bisogno di qualcosa di specifico, o più avanzato.
La documentazione di Boost Random è here.
Il campo dei PRNG (Pseudo Random Number Generators) è piuttosto vasto.
Prima di tutto devi capire che senza avere un input esterno (di solito fisico) non puoi ottenere una vera fonte di numeri casuali .. Ecco perché questi algoritmi si chiamano pseudo random: di solito usano un seme per inizializzare una posizione in una sequenza molto lunga che sembra casuale ma non è affatto casuale.
uno degli algoritmi più semplici è la lineare congruenziale Generator (LCG), che ha alcuni costraints per garantire una lunga sequenza e non è custodito tutto.
Un altro divertente (almeno per il nome) è il generatore Blum Blum Blum (BBS) che è insolito per i normali PRNG perché si basa sull'esponenziazione in modulo aritmetico dando una sicurezza paragonabile ad altri algoritmi come RSA e El Gamal in rompere la sequenza (anche se non sono sicuro della prova)
Una volta ho scritto un rapporto sui CRNG per un corso di Matematica Discreta. Per esso, ho smontato rand() in 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
quindi è un qualcosa di simile LCG (non testato) ...
int ms_rand(int& seed)
{
seed = seed*0x343fd+0x269EC3; // a=214013, b=2531011
return (seed >> 0x10) & 0x7FFF;
}
Il codice sorgente C per la libreria run-time Microsoft C è disponibile come parte di MSDN e rand()/srand() è incluso. Vedi ad esempio l'implementazione portabile di microsoft_rand qui: https://bitbucket.org/shlomif/fc-solve/src/dd80a812e8b3aba98a014d939ed77eb1ce764e04/fc-solve/source /board_gen/pi_make_microsoft_freecell_board.c?at=master (URL breve - http://is.gd/kAUmHW. –
- 1. Quali sono alcuni comuni algoritmi di messa a fuoco?
- 2. Quali sono le applicazioni pratiche degli algoritmi degli antenati più comuni?
- 3. Risorsa per apprendimento Algoritmi per gradi non CS/Matematica
- 4. Quali sono gli usi comuni di UDP?
- 5. Quali sono alcuni pattern di gioco 3D comuni?
- 6. Quali algoritmi sono disponibili per ridimensionare una tabella hash?
- 7. Quali sono gli hash (#) usati nella sorgente della libreria?
- 8. Quali algoritmi utilizza SQL?
- 9. GPU rispetto alle prestazioni della CPU per algoritmi comuni
- 10. Per cosa sono usati std :: vector :: front()?
- 11. Quali librerie/librerie Java per algoritmi genetici?
- 12. Quali sono gli algoritmi di analisi del sentimento esistenti?
- 13. Quali sono i colpevoli comuni della lentezza del TMP
- 14. C++: quali sono le vulnerabilità più comuni e come evitarle?
- 15. Quali sono i pattern DDD (Domain-Driven Design) comuni?
- 16. Quali sono alcuni algoritmi per confrontare come sono simili due stringhe?
- 17. Quali sono le reali differenze tra algoritmi genetici e algoritmi evolutivi?
- 18. Quali sono i modelli di progettazione di servizi Windows comuni?
- 19. Quali sono i modelli di progettazione più comuni in Cocoa Touch?
- 20. Crittografia Java: quali algoritmi dovrei usare?
- 21. Cosa sono usati session_id, session_regenerate_id e session_name?
- 22. Quali segnali possono essere tranquillamente usati per uccidere un processo Git e quali no?
- 23. Raggruppa per valore RAND()
- 24. Cosa sono i tick usati in PHP?
- 25. Quali sono gli errori più comuni da evitare durante la codifica di javascript per Internet Explorer?
- 26. Quali sono alcuni metodi comuni per causare perdite di memoria utilizzando JQuery/JavaScript?
- 27. Quali sono le insidie più comuni per un utente principiante Drupal?
- 28. Quali sono i nickname per i caratteri speciali di programmazione comuni?
- 29. Quali sono le convenzioni comuni per l'utilizzo degli spazi dei nomi in Clojure?
- 30. Double Hyphen/Dash in SQL-Injection. Per cosa sono usati?
Il commento principale è che rand() è solo pseudo- casuale, e spesso nemmeno un ottimo generatore pseudo-casuale. Lo standard C suggerisce una possibile implementazione e molte implementazioni lo utilizzano. Come altri hanno notato, ce ne sono molti altri. Assicurati di non utilizzare le funzioni casuali di base per le situazioni in cui hai bisogno di casualità crittografica. –