Hinweis : Nicht rand()aus Sicherheitsgründen verwenden. Wenn Sie eine kryptografisch sichere Nummer benötigen, lesen Sie stattdessen diese Antwort .
#include<time.h>#include<stdlib.h>
srand(time(NULL));// Initialization, should only be called once.int r = rand();// Returns a pseudo-random integer between 0 and RAND_MAX.
Bearbeiten : Unter Linux bevorzugen Sie möglicherweise die Verwendung von Random und Srandom .
Der Einfachheit halber +1, aber es ist wahrscheinlich eine gute Idee zu betonen, dass srand () nur einmal aufgerufen werden sollte . In einer Thread-Anwendung möchten Sie möglicherweise sicherstellen, dass der Status des Generators pro Thread gespeichert ist, und den Generator für jeden Thread einmal festlegen.
RBerteig
41
@trusktr, es ist kompliziert. Hier ist ein Grund: time()Änderungen nur einmal pro Sekunde. Wenn Sie time()für jeden Anruf an rand()einen Startwert festlegen , erhalten Sie für jeden Anruf innerhalb einer Sekunde den gleichen Wert. Der größere Grund ist jedoch, dass die Eigenschaften rand()und Funktionen wie diese am besten für den Anwendungsfall bekannt sind, bei dem sie genau einmal pro Lauf und nicht bei jedem einzelnen Aufruf gesetzt werden. Je nach "Zufälligkeit" mit ungetesteten oder unbewiesenen Eigenschaften kommt es zu Problemen.
RBerteig
9
@trusktr für einen einfachen linearen Kongruenzgenerator (was rand()normalerweise der Fall ist), mit dem Seeding rand()im besten Fall überhaupt keine Wirkung hat und im schlimmsten Fall die bekannten Eigenschaften des Generators beeinträchtigt. Dies ist ein tiefes Thema. Beginnen Sie mit dem Lesen von Knuth Vol 2 Kapitel 3 über Zufallszahlen als beste Einführung in die Mathematik und die Fallstricke.
RBerteig
21
Vermeiden Sie eine Compiler-Warnung mit einer Besetzung:srand((unsigned int)time(NULL));
GiovaMaster
9
Denken Sie daran, dass dies immer noch eine schwache Sichtweise auf das PRNG ist. Erst letztes Jahr machte ein Cryptolocker-Virus unter Linux den Fehler, mit der Zeit zu säen, und dies reduzierte den Suchraum dramatisch . Alles, was Sie tun mussten, war eine anständige Vorstellung davon zu bekommen, wann die Infektion auftrat, und dann Samen aus dieser Zeit zu probieren. Zuletzt habe ich gehört, dass die beste Quelle für Zufälligkeit / dev / urandom ist, die angeblich aus einem Mashup chaotischer Quellen wie Temperaturen auf der Hardware stammt. Wenn Sie jedoch nur möchten, dass Ihr Programm bei jedem Lauf anders funktioniert, ist die oben genannte Lösung in Ordnung.
Jemenake
238
Die rand()Funktion in <stdlib.h>gibt eine pseudozufällige Ganzzahl zwischen 0 und zurück RAND_MAX. Sie können srand(unsigned int seed)einen Startwert festlegen.
Es ist üblich, den %Operator in Verbindung mit rand()zu verwenden, um einen anderen Bereich zu erhalten (bedenken Sie jedoch, dass dies die Gleichmäßigkeit etwas beeinträchtigt). Zum Beispiel:
/* random int between 0 and 19 */int r = rand()%20;
Wenn Ihnen die Einheitlichkeit wirklich am Herzen liegt, können Sie Folgendes tun:
/* Returns an integer in the range [0, n).
*
* Uses rand(), and so is affected-by/affects the same seed.
*/int randint(int n){if((n -1)== RAND_MAX){return rand();}else{// Supporting larger values for n would requires an even more// elaborate implementation that combines multiple calls to rand()
assert (n <= RAND_MAX)// Chop off all of the values that would cause skew...int end = RAND_MAX / n;// truncate skew
assert (end >0);
end *= n;// ... and ignore results from rand() that fall above that limit.// (Worst case the loop condition should succeed 50% of the time,// so we can expect to bail out of this loop pretty quickly.)int r;while((r = rand())>= end);return r % n;}}
Es ist eine gängige Praxis , aber nicht die richtige. Sehen Sie dies und das .
Lazer
35
@Lazer: Deshalb habe ich gesagt "obwohl ich bedenke, dass dies die Gleichförmigkeit etwas beeinträchtigt".
Laurence Gonsalves
3
@AbhimanyuAryan Das %ist der Moduloperator . Es gibt Ihnen den Rest einer ganzzahligen Division, gibt Ihnen also x % nimmer eine Zahl zwischen 0und n - 1(solange xund nbeide positiv sind). Wenn Sie das immer noch verwirrend finden, schreiben Sie ein Programm mit einer iAnzahl von 0 bis 100 und drucken Sie es i % nfür einige nIhrer Auswahl aus, die kleiner als 100 sind.
Laurence Gonsalves
2
@necromancer Ich ging voran und fügte eine vollkommen einheitliche Lösung hinzu.
Laurence Gonsalves
2
@Lazer Der zweite Link, den du gepostet hast, ist eigentlich immer noch nicht perfekt einheitlich. Das Casting auf ein Doppel und zurück hilft nicht. Der erste Link, den Sie gepostet haben, hat eine vollkommen einheitliche Lösung, obwohl er für kleine Obergrenzen eine Menge Schleifen enthält . Ich habe dieser Antwort eine vollkommen einheitliche Lösung hinzugefügt, die selbst für kleine Obergrenzen nicht so viele Schleifen bilden sollte.
Laurence Gonsalves
53
Wenn Sie sichere zufällige Zeichen oder Ganzzahlen benötigen:
Im weiteren Sinne verwenden Sie/dev/urandom nicht /dev/random. Nicht OpenSSL (oder andere User-Space-PRNGs).
Zum Beispiel:
#include"sodium.h"int foo(){char myString[32];uint32_t myInt;if(sodium_init()<0){/* panic! the library couldn't be initialized, it is not safe to use */return1;}/* myString will be an array of 32 random bytes, not null-terminated */
randombytes_buf(myString,32);/* myInt will be a random number between 0 and 9 */
myInt = randombytes_uniform(10);}
randombytes_uniform() ist kryptografisch sicher und unvoreingenommen.
sollte libsodium RNG vor dem Aufruf von randombytes_buf gesetzt werden?
user2199593
Rufen Sie einfach sodium_init()irgendwann an. Mach dir keine Sorgen über das RNG, es verwendet den Kernel.
Scott Arciszewski
Hinweis: Ich habe die letzte Bearbeitung genehmigt, sodium_init()obwohl dies nicht unbedingt Teil meines Beispiels ist, da es sich um ein wichtiges Detail handelt.
Scott Arciszewski
29
Lass uns das durchgehen. Zuerst verwenden wir die Funktion srand (), um den Randomizer zu setzen. Grundsätzlich kann der Computer Zufallszahlen basierend auf der Zahl generieren, die srand () zugeführt wird. Wenn Sie denselben Startwert angeben, werden jedes Mal dieselben Zufallszahlen generiert.
Daher müssen wir den Randomizer mit einem Wert setzen, der sich ständig ändert. Dazu geben wir den Wert der aktuellen Zeit mit der Funktion time () ein.
Wenn wir nun rand () aufrufen, wird jedes Mal eine neue Zufallszahl erzeugt.
#include<stdio.h>int random_number(int min_num,int max_num);int main(void){
printf("Min : 1 Max : 40 %d\n", random_number(1,40));
printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));return0;}int random_number(int min_num,int max_num){int result =0, low_num =0, hi_num =0;if(min_num < max_num){
low_num = min_num;
hi_num = max_num +1;// include max_num in output}else{
low_num = max_num +1;// include max_num in output
hi_num = min_num;}
srand(time(NULL));
result =(rand()%(hi_num - low_num))+ low_num;return result;}
Netter Code, aber keine gute Idee, 'srand (time (NULL));' zu nennen. Diese Methode erzeugt dieselbe Nummer, wenn sie in einer for-Schleife aufgerufen wird.
RayOldProf
1
Vorgeschlagene Änderungen mit Code werden häufig abgelehnt. Jemand hat hier einen mit dem Kommentar "Algorithmus war falsch. Könnte größere Zahlen als das Maximum produzieren" gemacht. Ich habe die Behauptung nicht selbst bewertet.
Martin Smith
1
@ Martin Smith Probleme: 1) sollte sein else{ low_num=max_num; hi_num=min_num+1;2) schlägt fehl wenn hi_num - low_num > INT_MAX. 3) Lässt Werte in der seltenen Situation aus INT_MAX > hi_num - low_num > RAND_MAX.
chux
1
Wenn Sie es so erneut festlegen, erzeugt diese Funktion dieselbe Nummer, wenn sie in derselben Sekunde mehrmals aufgerufen wird. Wenn Sie es wirklich neu säen möchten, säen Sie es nur einmal pro Sekunde neu.
Élektra
1
Klein: hi_num = max_num + 1;Mangel an Überlaufschutz.
chux
25
Wenn Sie Pseudozufallszahlen von besserer Qualität benötigen als diese stdlib, schauen Sie sich Mersenne Twister an . Es ist auch schneller. Beispielimplementierungen sind beispielsweise hier reichlich vorhanden .
+1: Sieht cool aus, aber ich habe gerade ein Ratespiel gemacht. Wenn ich in einer Geschäftsanwendung einen Zufallszahlengenerator verwenden würde, würde ich diesen definitiv verwenden.
Kredns
4
Verwenden Sie keinen Mersenne Twister, sondern etwas Gutes wie xoroshiro128 + oder PCG. (Relevanter Link.)
Veedrac
17
Die Standard-C-Funktion ist rand(). Es ist gut genug, um Karten für Solitaire zu geben, aber es ist schrecklich. Viele Implementierungen von rand()Zyklen durch eine kurze Liste von Zahlen, und die niedrigen Bits haben kürzere Zyklen. Die Art rand()und Weise, wie manche Programme aufrufen, ist schrecklich, und es srand()ist schwierig , einen guten Startwert zu berechnen .
Der beste Weg, um Zufallszahlen in C zu generieren, ist die Verwendung einer Drittanbieter-Bibliothek wie OpenSSL. Zum Beispiel,
#include<stdint.h>#include<stdio.h>#include<stdlib.h>#include<openssl/rand.h>/* Random integer in [0, limit) */unsignedint random_uint(unsignedint limit){union{unsignedint i;unsignedchar c[sizeof(unsignedint)];} u;do{if(!RAND_bytes(u.c,sizeof(u.c))){
fprintf(stderr,"Can't get random bytes!\n");
exit(1);}}while(u.i <(-limit % limit));/* u.i < (2**size % limit) */return u.i % limit;}/* Random double in [0.0, 1.0) */double random_double(){union{uint64_t i;unsignedchar c[sizeof(uint64_t)];} u;if(!RAND_bytes(u.c,sizeof(u.c))){
fprintf(stderr,"Can't get random bytes!\n");
exit(1);}/* 53 bits / 2**53 */return(u.i >>11)*(1.0/9007199254740992.0);}int main(){
printf("Dice: %d\n",(int)(random_uint(6)+1));
printf("Double: %f\n", random_double());return0;}
Warum so viel Code? Andere Sprachen wie Java und Ruby haben Funktionen für zufällige Ganzzahlen oder Gleitkommazahlen. OpenSSL gibt nur zufällige Bytes an, daher versuche ich nachzuahmen, wie Java oder Ruby sie in Ganzzahlen oder Floats umwandeln würden.
Für ganze Zahlen wollen wir Modulo Bias vermeiden . Angenommen, wir haben zufällige 4-stellige Ganzzahlen erhalten rand() % 10000, können aber rand()nur 0 bis 32767 zurückgeben (wie in Microsoft Windows). Jede Zahl von 0 bis 2767 wird häufiger angezeigt als jede Zahl von 2768 bis 9999. Um die Abweichung zu beseitigen, können wir es erneut versuchen, rand()während der Wert unter 2768 liegt, da die 30000-Werte von 2768 bis 32767 einheitlich auf die 10000-Werte von 0 bis abgebildet werden 9999.
Für Floats benötigen wir 53 zufällige Bits, da a eine doubleGenauigkeit von 53 Bit enthält (vorausgesetzt, es handelt sich um ein IEEE-Double). Wenn wir mehr als 53 Bits verwenden, erhalten wir eine Rundungsvorspannung. Einige Programmierer schreiben Code wie rand() / (double)RAND_MAX, geben jedoch rand()möglicherweise nur 31 Bit oder nur 15 Bit in Windows zurück.
OpenSSLs RAND_bytes()Samen selbst, vielleicht durch Lesen /dev/urandomin Linux. Wenn wir viele Zufallszahlen benötigen, wäre es zu langsam, sie alle zu lesen /dev/urandom, da sie aus dem Kernel kopiert werden müssen. Es ist schneller, OpenSSL zu erlauben, mehr Zufallszahlen aus einem Startwert zu generieren.
Mehr über Zufallszahlen:
Perls Perl_seed () ist ein Beispiel für die Berechnung eines Seeds in C für srand(). Es mischt Bits aus der aktuellen Zeit, der Prozess-ID und einigen Zeigern, wenn es nicht lesen kann /dev/urandom.
Die Java-API für java.util.Random beschreibt Algorithmen zum Entfernen von Verzerrungen aus zufälligen Ganzzahlen und zum Packen von 53 Bit in zufällige Gleitkommazahlen.
Vielen Dank für diese erweiterte Antwort. Beachten Sie, dass Sie von den 24 aktuellen Antworten auf diese Frage die einzige mit einer zusätzlichen Interpretation waren, die sich mit float/ doublebefasste. Daher habe ich die Frage geklärt, sich an intZahlen zu halten, um zu vermeiden, dass sie zu weit gefasst wird. Es gibt andere C-Fragen, die sich speziell mit float/ doublezufälligen Werten befassen. Daher möchten Sie möglicherweise Ihre zweite Hälfte Ihrer Antwort auf Fragen wie stackoverflow.com/questions/13408990/…
Cœur
11
Wenn Ihr System die arc4randomFunktionsfamilie unterstützt, würde ich empfehlen, diese anstelle der Standardfunktion zu randverwenden.
arc4random Gibt eine zufällige vorzeichenlose 32-Bit-Ganzzahl zurück.
arc4random_buffügt zufälligen Inhalt in seinen Parameter ein buf : void *. Die Menge des Inhalts wird durch den bytes : size_tParameter bestimmt.
arc4random_uniformGibt eine zufällige vorzeichenlose 32-Bit-Ganzzahl zurück, die der Regel folgt: 0 <= arc4random_uniform(limit) < limitwobei limit auch eine vorzeichenlose 32-Bit-Ganzzahl ist.
arc4random_stirliest Daten aus /dev/urandomund übergibt die Daten an, arc4random_addrandomum den internen Zufallszahlenpool zusätzlich zu randomisieren.
arc4random_addrandomwird verwendet, um arc4random_stirden internen Zufallszahlenpool entsprechend den an ihn übergebenen Daten zu füllen.
Wenn Sie diese Funktionen nicht haben, aber unter Unix arbeiten, können Sie diesen Code verwenden:
/* This is C, not C++ */#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<errno.h>#include<unistd.h>#include<stdlib.h>/* exit */#include<stdio.h>/* printf */int urandom_fd =-2;void urandom_init(){
urandom_fd = open("/dev/urandom", O_RDONLY);if(urandom_fd ==-1){int errsv = urandom_fd;
printf("Error opening [/dev/urandom]: %i\n", errsv);
exit(1);}}unsignedlong urandom(){unsignedlong buf_impl;unsignedlong*buf =&buf_impl;if(urandom_fd ==-2){
urandom_init();}/* Read 4 bytes, or 32 bits into *buf, which points to buf_impl */
read(urandom_fd, buf,sizeof(long));return buf_impl;}
Die urandom_initFunktion öffnet das /dev/urandomGerät und fügt den Dateideskriptor ein urandom_fd.
Die urandomFunktion ist im Grunde die gleiche wie ein Aufruf von rand, außer sicherer, und sie gibt a zurück long(leicht änderbar).
Da /dev/urandomdies jedoch etwas langsam sein kann, wird empfohlen, es als Startwert für einen anderen Zufallszahlengenerator zu verwenden.
Wenn Ihr System einen nicht haben /dev/urandom, aber nicht eine hat /dev/randomoder ähnliche Datei, dann können Sie einfach den Pfad zu übergeben ändern openin urandom_init. Die in urandom_initund urandommeiner Meinung nach POSIX-kompatiblen Aufrufe und APIs sollten als solche auf den meisten, wenn nicht allen POSIX-kompatiblen Systemen funktionieren.
Hinweise: Ein Lesevorgang /dev/urandomwird NICHT blockiert, wenn nicht genügend Entropie verfügbar ist. Daher können unter solchen Umständen generierte Werte kryptografisch unsicher sein. Wenn Sie sich darüber Sorgen machen, verwenden Sie diese Option /dev/random, die bei unzureichender Entropie immer blockiert.
Wenn Sie sich auf einem anderen System (z. B. Windows) befinden, verwenden Sie randoder eine interne Windows-spezifische plattformabhängige nicht portierbare API.
Wrapper - Funktion für urandom, randoder arc4randomAnrufe:
STL existiert nicht für C. Sie müssen anrufen randoder noch besser random. Diese werden im Standardbibliotheksheader deklariert stdlib.h. randist POSIX, randomist eine BSD-Spezifikationsfunktion.
Der Unterschied zwischen randund randombesteht darin, dass randomeine viel besser verwendbare 32-Bit-Zufallszahl und randnormalerweise eine 16-Bit-Zahl zurückgegeben wird. Die BSD-Manpages zeigen, dass die unteren Bits von randzyklisch und vorhersehbar sind und daher randfür kleine Zahlen möglicherweise unbrauchbar sind.
@Neil - da alle Antworten bisher die STL erwähnen, vermute ich, dass die Frage schnell bearbeitet wurde, um unnötige Verweise zu entfernen.
Michael Burr
rand () ist für kleine Zahlen nicht nutzlos - Sie können sie herausschieben und nur die zufälligeren hohen Bits verwenden, wenn Sie es wirklich brauchen.
Chris Lutz
@Chris können Sie, wenn die Größe der Zufallszahl bekannt ist, aber wenn sich die erforderliche Größe der Zufallszahl zur Laufzeit ändert (z. B. das Mischen eines dynamischen Arrays usw.), ist es schwierig, eine solche Einschränkung zu umgehen.
@ kasia.b in diesem Link gibt es extern int rand(void);und extern void srand(unsigned int);.
RastaJedi
7
Schauen Sie sich ISAAC an (Indirektion, Verschiebung, Akkumulieren, Hinzufügen und Zählen). Es ist gleichmäßig verteilt und hat eine durchschnittliche Zykluslänge von 2 ^ 8295.
Sie möchten verwenden rand(). Hinweis ( SEHR WICHTIG ): Stellen Sie sicher, dass Sie den Startwert für die Rand-Funktion festlegen. Wenn Sie dies nicht tun, sind Ihre Zufallszahlen nicht wirklich zufällig . Das ist sehr, sehr, sehr wichtig. Zum Glück können Sie normalerweise eine Kombination aus dem System-Ticks-Timer und dem Datum verwenden, um einen guten Startwert zu erhalten.
Zwei Punkte a) Ihre Zufallszahlen sind nicht "wirklich" zufällig, egal wie Sie den Generator setzen. Und b) es ist sehr praktisch, dass die Pseudozufallsfolge unter vielen Umständen immer dieselbe ist - zum Beispiel zum Testen.
16
Wenn es SEHR WICHTIG ist, dass Ihre Zahl wirklich zufällig ist, sollten Sie die Funktion rand () nicht verwenden.
Tyler
1
Die Werte von rand sind überhaupt nicht "wirklich" zufällig, egal ob Sie den Startwert setzen oder nicht. Bei einem bekannten Startwert ist die Sequenz vorhersehbar. "Wirklich" Zufallszahlengenerierung ist schwierig. Mit Rand ist keine Entropie verbunden.
Dreamlax
2
Natürlich werden sie - der Generator wird von der Bibliothek für Sie gesetzt (wahrscheinlich auf Null, aber das ist ein gültiger Samen).
4
Ah, aber ein bekannter Algorithmus / bekannter Startwert ist wichtig für das Debuggen eines Programms, das Zufallszahlen verwendet. Es ist nicht ungewöhnlich, den verwendeten Startwert zusammen mit einem Simulationslauf zu protokollieren, damit er für eine detailliertere Analyse neu erstellt werden kann. Das Nichtaufrufen von srand () entspricht dem Aufrufen von srand (1).
RBerteig
4
FWIW, die Antwort lautet: Ja, es gibt eine stdlib.hFunktion namens rand; Diese Funktion ist in erster Linie auf Geschwindigkeit und Verteilung abgestimmt, nicht auf Unvorhersehbarkeit. Fast alle integrierten Zufallsfunktionen für verschiedene Sprachen und Frameworks verwenden diese Funktion standardmäßig. Es gibt auch "kryptografische" Zufallszahlengeneratoren, die viel weniger vorhersehbar sind, aber viel langsamer laufen. Diese sollten in jeder sicherheitsrelevanten Anwendung verwendet werden.
Das Hinzufügen von srand (rand ()) erhöht die Zufälligkeit der Sequenz nicht, wenn dieses Programm innerhalb von 1 Sekunde mehrmals ausgeführt wird. time (NULL) gibt immer noch den gleichen Wert für jeden von ihnen zurück, der erste rand () gibt den gleichen langen Wert zurück und der zweite Aufruf von srand () hat den gleichen Wert, was dazu führt, dass immer noch die gleiche Zufallsfolge vorliegt. Die Verwendung der Adresse von argc kann nur dann hilfreich sein, wenn garantiert ist, dass diese Adresse bei jeder Ausführung des Programms unterschiedlich ist, was nicht immer der Fall ist.
theferrit32
3
Nun, STL ist C ++, nicht C, also weiß ich nicht, was Sie wollen. Wenn Sie jedoch C möchten, gibt es die rand()und srand()-Funktionen:
int rand(void);void srand(unsigned seed);
Diese sind beide Teil von ANSI C. Es gibt auch die random()Funktion:
long random(void);
Aber soweit ich das beurteilen kann, random()handelt es sich nicht um Standard-ANSI C. Eine Bibliothek von Drittanbietern ist möglicherweise keine schlechte Idee, aber alles hängt davon ab, wie zufällig eine Zahl ist, die Sie wirklich generieren müssen.
Zu dem Zeitpunkt, als ich diesen Kommentar abgegeben habe, hatte ich keine universellen Bearbeitungsberechtigungen, und im Allgemeinen werden Codeänderungen, die die tatsächliche Antwort geändert haben, abgelehnt. Wenn Sie Ihre Antwort nicht korrigieren möchten, kann ich das trotzdem.
b4hand
Wenn Sie beabsichtigen, eine zufällige Permutation eindeutiger Werte zu erstellen, weist dieser Code immer noch einen Fehler auf. Es erzeugt den Wert 84 zweimal und nicht den Wert 48. Außerdem wird der Zufallszahlengenerator nicht gesetzt, sodass die Reihenfolge bei jeder Ausführung gleich ist.
b4hand
1
Die Variablen a und b sind in diesem Code definiert. Es ist fehlerfrei. Es gibt auch keine Syntax und keinen logischen Fehler.
Muhammad Sadiq
Falsch. Ich habe die Ausgabe bereits von Hand bestätigt, wie ich bereits erwähnt habe.
b4hand
1
#include<stdio.h>#include<dos.h>int random(int range);int main(void){
printf("%d", random(10));return0;}int random(int range){struct time t;int r;
gettime(&t);
r = t.ti_sec % range;return r;}
Auf modernen x86_64-CPUs können Sie den Hardware-Zufallszahlengenerator über verwenden _rdrand64_step()
Beispielcode:
#include<immintrin.h>uint64_t randVal;if(!_rdrand64_step(&randVal)){// Report an error here: random number generation has failed!}// If no error occured, randVal contains a random 64-bit number
#include<stdio.h>#include<stdlib.h>#include<time.h>//generate number in range [min,max)int random(int min,int max){int number = min + rand()%(max - min);return number;}//Driver codeint main(){
srand(time(NULL));for(int i =1; i <=10; i++){
printf("%d\t", random(10,100));}return0;}
Als rand()ich eine gute Erklärung hörte, warum es eine schlechte Idee ist, gleichmäßig verteilte Zufallszahlen in einem bestimmten Bereich zu erzeugen, beschloss ich, einen Blick darauf zu werfen, wie verzerrt die Ausgabe tatsächlich ist. Mein Testfall war faires Würfeln. Hier ist der C-Code:
#include<stdio.h>#include<stdlib.h>#include<time.h>int main(int argc,char*argv[]){int i;int dice[6];for(i =0; i <6; i++)
dice[i]=0;
srand(time(NULL));constint TOTAL =10000000;for(i =0; i < TOTAL; i++)
dice[(rand()%6)]+=1;double pers =0.0, tpers =0.0;for(i =0; i <6; i++){
pers =(dice[i]*100.0)/ TOTAL;
printf("\t%1d %5.2f%%\n", dice[i], pers);
tpers += pers;}
printf("\ttotal: %6.2f%%\n", tpers);}
rand () kann andere Zufälligkeitstests wie die eingefleischten Tests nicht bestehen . rand () unterscheidet sich von Plattform zu Plattform; rand () -Werte von GNU / Linux sind möglicherweise besser als Werte von BSD oder Windows.
George Koehler
Dies ist keine gültige Methode zum Testen der Zufälligkeit.
Veedrac
Hängt vom Zweck und dem Bedrohungs- / Risikomodell ab. Verwenden Sie für kryptografisch starkes RNG RDRAND (oder RDSEED). Für einen einfachen Würfelwerfer (nicht auf Casino-Ebene) sollte meiner Meinung nach das oben Genannte ausreichen. Das Schlüsselwort lautet "gut genug ".
Maus
0
Ich hatte in meiner letzten Anwendung ein ernstes Problem mit dem Pseudozufallszahlengenerator: Ich habe mein C-Programm wiederholt über ein Pyhton-Skript aufgerufen und den folgenden Code als Startwert verwendet:
srand(time(NULL))
Da jedoch:
rand erzeugt die gleiche Pseudozufallssequenz und gibt den gleichen Startwert in srand (siehe man srand );
Wie bereits erwähnt, ändert sich die Zeitfunktion nur von Sekunde zu Sekunde: Wenn Ihre Anwendung innerhalb derselben Sekunde mehrmals ausgeführt wird, time wird wird jedes Mal derselbe Wert zurückgegeben.
Mein Programm hat die gleiche Zahlenfolge generiert. Sie können drei Dinge tun, um dieses Problem zu lösen:
Mischzeitausgabe mit einigen anderen Informationen, die sich bei Läufen ändern (in meiner Anwendung der Ausgabename):
Option 3 stellt sicher, dass Sie (soweit ich weiß) die beste Zufalls-Zufälligkeit haben, kann jedoch nur bei sehr schneller Anwendung einen Unterschied bewirken. Meiner Meinung nach ist Option 2 eine sichere Wette.
Verlassen Sie sich auch bei diesen Heuristiken nicht auf rand () für kryptografische Daten.
Domenukk
rand()sollte nicht für kryptografische Daten verwendet werden, stimme ich zu. Zumindest für mich enthielt meine Anwendung keine kryptografischen Daten, daher war die angegebene Methode für mich in Ordnung.
Koldar
0
Trotz aller Vorschläge der Leute rand()hier möchten Sie nicht verwenden, es rand()sei denn, Sie müssen! Die Zufallszahlen, dierand() erzeugt werden sind oft sehr schlecht. Um aus der Linux-Manpage zu zitieren:
Die Versionen von rand()und srand()in der Linux C-Bibliothek verwenden denselben Zufallszahlengenerator wie random(3)und srandom(3), daher sollten die Bits niedrigerer Ordnung genauso zufällig sein wie die Bits höherer Ordnung. Bei älteren rand () - Implementierungen und bei aktuellen Implementierungen auf verschiedenen Systemen sind die Bits niedrigerer Ordnung jedoch viel weniger zufällig als die Bits höherer Ordnung . Verwenden Sie diese Funktion nicht in Anwendungen, die portabel sein sollen, wenn eine gute Zufälligkeit erforderlich ist. ( Verwenden Sie random(3)stattdessen. )
In Bezug auf die Portabilität random()wird dies seit geraumer Zeit auch vom POSIX-Standard definiert. rand()älter ist, erschien es bereits in der ersten POSIX.1-Spezifikation (IEEE Std 1003.1-1988), wohingegenrandom() zuerst in POSIX.1-2001 (IEEE Std 1003.1-2001) erschien, der aktuelle POSIX-Standard ist jedoch bereits POSIX.1-2008 (IEEE Std 1003.1-2008), die vor einem Jahr ein Update erhalten hat (IEEE Std 1003.1-2008, Ausgabe 2016). Daher würde ich es als random()sehr tragbar betrachten.
POSIX.1-2001 führte auch die Funktionen lrand48()und ein mrand48(), siehe hier :
Diese Funktionsfamilie soll Pseudozufallszahlen unter Verwendung eines linearen Kongruenzalgorithmus und einer 48-Bit-Ganzzahlarithmetik erzeugen.
Und eine ziemlich gute Pseudozufallsquelle ist die arc4random()Funktion, die auf vielen Systemen verfügbar ist. Nicht Teil eines offiziellen Standards, erschien um 1997 in BSD, aber Sie können ihn auf Systemen wie Linux und macOS / iOS finden.
@ BjörnLindqvist Windows ist auch kein POSIX-System; Es ist so ziemlich das einzige System auf dem Markt, das zumindest die Basis-POSIX-APIs nicht unterstützt (die sogar gesperrte Systeme wie iOS unterstützen). Windows wird nur unterstützt, rand()da dies auch vom C-Standard verlangt wird. Für alles andere benötigen Sie wie gewohnt nur eine spezielle Lösung für Windows. #ifdef _WIN32ist der Ausdruck, den Sie am häufigsten in plattformübergreifendem Code sehen, der Windows unterstützen möchte. In der Regel gibt es eine Lösung, die mit allen Systemen funktioniert, und eine, die nur für Windows erforderlich ist.
Mecki
0
Für Linux C-Anwendungen:
Dies ist mein überarbeiteter Code aus einer Antwort oben, die meinen C-Code-Praktiken folgt und einen zufälligen Puffer beliebiger Größe (mit geeigneten Rückkehrcodes usw.) zurückgibt. Stellen Sie sicher, dass Sie zu urandom_open()Beginn Ihres Programms einmal aufrufen .
int gUrandomFd =-1;int urandom_open(void){if(gUrandomFd ==-1){
gUrandomFd = open("/dev/urandom", O_RDONLY);}if(gUrandomFd ==-1){
fprintf(stderr,"Error opening /dev/urandom: errno [%d], strerrer [%s]\n",
errno, strerror(errno));return-1;}else{return0;}}void urandom_close(void){
close(gUrandomFd);
gUrandomFd =-1;}//// This link essentially validates the merits of /dev/urandom:// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers///int getRandomBuffer(uint8_t*buf,int size){int ret =0;// Return valueif(gUrandomFd ==-1){
fprintf(stderr,"Urandom (/dev/urandom) file not open\n");return-1;}
ret = read(gUrandomFd, buf, size);if(ret != size){
fprintf(stderr,"Only read [%d] bytes, expected [%d]\n",
ret, size);return-1;}else{return0;}}
Meine minimalistische Lösung sollte für Zufallszahlen im Bereich funktionieren [min, max). Verwenden Sie diese srand(time(NULL))Option, bevor Sie die Funktion aufrufen.
int range_rand(int min_num,int max_num){if(min_num >= max_num){
fprintf(stderr,"min_num is greater or equal than max_num!\n");}return min_num +(rand()%(max_num - min_num));}
Versuchen Sie dies, ich habe es aus einigen der Konzepte zusammengestellt, auf die oben bereits verwiesen wurde:
/*
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
*/int random(int max){
srand((unsigned) time(NULL));return(rand()% max)+1;}
Dieser Code ist nicht gut. Es ist eine schreckliche Idee, srand()jedes Mal anzurufen, wenn Sie anrufen möchten rand(). Da time()normalerweise ein Wert in Sekunden zurückgegeben wird , gibt das schnelle Aufrufen dieser Funktion denselben "zufälligen" Wert zurück.
Blastfurnace
3
Diese Funktion würde mit der Unix- random()Funktion verwechselt .
srand
: Warum nur einmal anrufen .Antworten:
Bearbeiten : Unter Linux bevorzugen Sie möglicherweise die Verwendung von Random und Srandom .
quelle
time()
Änderungen nur einmal pro Sekunde. Wenn Sietime()
für jeden Anruf anrand()
einen Startwert festlegen , erhalten Sie für jeden Anruf innerhalb einer Sekunde den gleichen Wert. Der größere Grund ist jedoch, dass die Eigenschaftenrand()
und Funktionen wie diese am besten für den Anwendungsfall bekannt sind, bei dem sie genau einmal pro Lauf und nicht bei jedem einzelnen Aufruf gesetzt werden. Je nach "Zufälligkeit" mit ungetesteten oder unbewiesenen Eigenschaften kommt es zu Problemen.rand()
normalerweise der Fall ist), mit dem Seedingrand()
im besten Fall überhaupt keine Wirkung hat und im schlimmsten Fall die bekannten Eigenschaften des Generators beeinträchtigt. Dies ist ein tiefes Thema. Beginnen Sie mit dem Lesen von Knuth Vol 2 Kapitel 3 über Zufallszahlen als beste Einführung in die Mathematik und die Fallstricke.srand((unsigned int)time(NULL));
Die
rand()
Funktion in<stdlib.h>
gibt eine pseudozufällige Ganzzahl zwischen 0 und zurückRAND_MAX
. Sie könnensrand(unsigned int seed)
einen Startwert festlegen.Es ist üblich, den
%
Operator in Verbindung mitrand()
zu verwenden, um einen anderen Bereich zu erhalten (bedenken Sie jedoch, dass dies die Gleichmäßigkeit etwas beeinträchtigt). Zum Beispiel:Wenn Ihnen die Einheitlichkeit wirklich am Herzen liegt, können Sie Folgendes tun:
quelle
%
ist der Moduloperator . Es gibt Ihnen den Rest einer ganzzahligen Division, gibt Ihnen alsox % n
immer eine Zahl zwischen0
undn - 1
(solangex
undn
beide positiv sind). Wenn Sie das immer noch verwirrend finden, schreiben Sie ein Programm mit eineri
Anzahl von 0 bis 100 und drucken Sie esi % n
für einigen
Ihrer Auswahl aus, die kleiner als 100 sind.Wenn Sie sichere zufällige Zeichen oder Ganzzahlen benötigen:
Im Abschnitt zum sicheren Generieren von Zufallszahlen in verschiedenen Programmiersprachen sollten Sie einen der folgenden Schritte ausführen:
randombytes
API von libsodium/dev/urandom
nicht/dev/random
. Nicht OpenSSL (oder andere User-Space-PRNGs).Zum Beispiel:
randombytes_uniform()
ist kryptografisch sicher und unvoreingenommen.quelle
sodium_init()
irgendwann an. Mach dir keine Sorgen über das RNG, es verwendet den Kernel.sodium_init()
obwohl dies nicht unbedingt Teil meines Beispiels ist, da es sich um ein wichtiges Detail handelt.Lass uns das durchgehen. Zuerst verwenden wir die Funktion srand (), um den Randomizer zu setzen. Grundsätzlich kann der Computer Zufallszahlen basierend auf der Zahl generieren, die srand () zugeführt wird. Wenn Sie denselben Startwert angeben, werden jedes Mal dieselben Zufallszahlen generiert.
Daher müssen wir den Randomizer mit einem Wert setzen, der sich ständig ändert. Dazu geben wir den Wert der aktuellen Zeit mit der Funktion time () ein.
Wenn wir nun rand () aufrufen, wird jedes Mal eine neue Zufallszahl erzeugt.
quelle
else{ low_num=max_num; hi_num=min_num+1;
2) schlägt fehl wennhi_num - low_num > INT_MAX
. 3) Lässt Werte in der seltenen Situation ausINT_MAX > hi_num - low_num > RAND_MAX
.hi_num = max_num + 1;
Mangel an Überlaufschutz.Wenn Sie Pseudozufallszahlen von besserer Qualität benötigen als diese
stdlib
, schauen Sie sich Mersenne Twister an . Es ist auch schneller. Beispielimplementierungen sind beispielsweise hier reichlich vorhanden .quelle
Die Standard-C-Funktion ist
rand()
. Es ist gut genug, um Karten für Solitaire zu geben, aber es ist schrecklich. Viele Implementierungen vonrand()
Zyklen durch eine kurze Liste von Zahlen, und die niedrigen Bits haben kürzere Zyklen. Die Artrand()
und Weise, wie manche Programme aufrufen, ist schrecklich, und essrand()
ist schwierig , einen guten Startwert zu berechnen .Der beste Weg, um Zufallszahlen in C zu generieren, ist die Verwendung einer Drittanbieter-Bibliothek wie OpenSSL. Zum Beispiel,
Warum so viel Code? Andere Sprachen wie Java und Ruby haben Funktionen für zufällige Ganzzahlen oder Gleitkommazahlen. OpenSSL gibt nur zufällige Bytes an, daher versuche ich nachzuahmen, wie Java oder Ruby sie in Ganzzahlen oder Floats umwandeln würden.
Für ganze Zahlen wollen wir Modulo Bias vermeiden . Angenommen, wir haben zufällige 4-stellige Ganzzahlen erhalten
rand() % 10000
, können aberrand()
nur 0 bis 32767 zurückgeben (wie in Microsoft Windows). Jede Zahl von 0 bis 2767 wird häufiger angezeigt als jede Zahl von 2768 bis 9999. Um die Abweichung zu beseitigen, können wir es erneut versuchen,rand()
während der Wert unter 2768 liegt, da die 30000-Werte von 2768 bis 32767 einheitlich auf die 10000-Werte von 0 bis abgebildet werden 9999.Für Floats benötigen wir 53 zufällige Bits, da a eine
double
Genauigkeit von 53 Bit enthält (vorausgesetzt, es handelt sich um ein IEEE-Double). Wenn wir mehr als 53 Bits verwenden, erhalten wir eine Rundungsvorspannung. Einige Programmierer schreiben Code wierand() / (double)RAND_MAX
, geben jedochrand()
möglicherweise nur 31 Bit oder nur 15 Bit in Windows zurück.OpenSSLs
RAND_bytes()
Samen selbst, vielleicht durch Lesen/dev/urandom
in Linux. Wenn wir viele Zufallszahlen benötigen, wäre es zu langsam, sie alle zu lesen/dev/urandom
, da sie aus dem Kernel kopiert werden müssen. Es ist schneller, OpenSSL zu erlauben, mehr Zufallszahlen aus einem Startwert zu generieren.Mehr über Zufallszahlen:
srand()
. Es mischt Bits aus der aktuellen Zeit, der Prozess-ID und einigen Zeigern, wenn es nicht lesen kann/dev/urandom
.quelle
float
/double
befasste. Daher habe ich die Frage geklärt, sich anint
Zahlen zu halten, um zu vermeiden, dass sie zu weit gefasst wird. Es gibt andere C-Fragen, die sich speziell mitfloat
/double
zufälligen Werten befassen. Daher möchten Sie möglicherweise Ihre zweite Hälfte Ihrer Antwort auf Fragen wie stackoverflow.com/questions/13408990/…Wenn Ihr System die
arc4random
Funktionsfamilie unterstützt, würde ich empfehlen, diese anstelle der Standardfunktion zurand
verwenden.Die
arc4random
Familie umfasst:arc4random
Gibt eine zufällige vorzeichenlose 32-Bit-Ganzzahl zurück.arc4random_buf
fügt zufälligen Inhalt in seinen Parameter einbuf : void *
. Die Menge des Inhalts wird durch denbytes : size_t
Parameter bestimmt.arc4random_uniform
Gibt eine zufällige vorzeichenlose 32-Bit-Ganzzahl zurück, die der Regel folgt:0 <= arc4random_uniform(limit) < limit
wobei limit auch eine vorzeichenlose 32-Bit-Ganzzahl ist.arc4random_stir
liest Daten aus/dev/urandom
und übergibt die Daten an,arc4random_addrandom
um den internen Zufallszahlenpool zusätzlich zu randomisieren.arc4random_addrandom
wird verwendet, umarc4random_stir
den internen Zufallszahlenpool entsprechend den an ihn übergebenen Daten zu füllen.Wenn Sie diese Funktionen nicht haben, aber unter Unix arbeiten, können Sie diesen Code verwenden:
Die
urandom_init
Funktion öffnet das/dev/urandom
Gerät und fügt den Dateideskriptor einurandom_fd
.Die
urandom
Funktion ist im Grunde die gleiche wie ein Aufruf vonrand
, außer sicherer, und sie gibt a zurücklong
(leicht änderbar).Da
/dev/urandom
dies jedoch etwas langsam sein kann, wird empfohlen, es als Startwert für einen anderen Zufallszahlengenerator zu verwenden.Wenn Ihr System einen nicht haben
/dev/urandom
, aber nicht eine hat/dev/random
oder ähnliche Datei, dann können Sie einfach den Pfad zu übergeben ändernopen
inurandom_init
. Die inurandom_init
undurandom
meiner Meinung nach POSIX-kompatiblen Aufrufe und APIs sollten als solche auf den meisten, wenn nicht allen POSIX-kompatiblen Systemen funktionieren.Hinweise: Ein Lesevorgang
/dev/urandom
wird NICHT blockiert, wenn nicht genügend Entropie verfügbar ist. Daher können unter solchen Umständen generierte Werte kryptografisch unsicher sein. Wenn Sie sich darüber Sorgen machen, verwenden Sie diese Option/dev/random
, die bei unzureichender Entropie immer blockiert.Wenn Sie sich auf einem anderen System (z. B. Windows) befinden, verwenden Sie
rand
oder eine interne Windows-spezifische plattformabhängige nicht portierbare API.Wrapper - Funktion für
urandom
,rand
oderarc4random
Anrufe:quelle
STL existiert nicht für C. Sie müssen anrufen
rand
oder noch besserrandom
. Diese werden im Standardbibliotheksheader deklariertstdlib.h
.rand
ist POSIX,random
ist eine BSD-Spezifikationsfunktion.Der Unterschied zwischen
rand
undrandom
besteht darin, dassrandom
eine viel besser verwendbare 32-Bit-Zufallszahl undrand
normalerweise eine 16-Bit-Zahl zurückgegeben wird. Die BSD-Manpages zeigen, dass die unteren Bits vonrand
zyklisch und vorhersehbar sind und daherrand
für kleine Zahlen möglicherweise unbrauchbar sind.quelle
extern int rand(void);
undextern void srand(unsigned int);
.Schauen Sie sich ISAAC an (Indirektion, Verschiebung, Akkumulieren, Hinzufügen und Zählen). Es ist gleichmäßig verteilt und hat eine durchschnittliche Zykluslänge von 2 ^ 8295.
quelle
Dies ist ein guter Weg, um eine Zufallszahl zwischen zwei Zahlen Ihrer Wahl zu erhalten.
Erstmalige Ausgabe: 39
Beim zweiten Mal ausgeben: 61
Zum dritten Mal ausgeben: 65
Sie können die Werte danach
randnum
in beliebige Zahlen ändern , und es wird eine Zufallszahl zwischen diesen beiden Zahlen für Sie generiert.quelle
Sie möchten verwenden
rand()
. Hinweis ( SEHR WICHTIG ): Stellen Sie sicher, dass Sie den Startwert für die Rand-Funktion festlegen. Wenn Sie dies nicht tun, sind Ihre Zufallszahlen nicht wirklich zufällig . Das ist sehr, sehr, sehr wichtig. Zum Glück können Sie normalerweise eine Kombination aus dem System-Ticks-Timer und dem Datum verwenden, um einen guten Startwert zu erhalten.quelle
FWIW, die Antwort lautet: Ja, es gibt eine
stdlib.h
Funktion namensrand
; Diese Funktion ist in erster Linie auf Geschwindigkeit und Verteilung abgestimmt, nicht auf Unvorhersehbarkeit. Fast alle integrierten Zufallsfunktionen für verschiedene Sprachen und Frameworks verwenden diese Funktion standardmäßig. Es gibt auch "kryptografische" Zufallszahlengeneratoren, die viel weniger vorhersehbar sind, aber viel langsamer laufen. Diese sollten in jeder sicherheitsrelevanten Anwendung verwendet werden.quelle
Dies ist hoffentlich etwas zufälliger als nur zu verwenden
srand(time(NULL))
.quelle
Nun, STL ist C ++, nicht C, also weiß ich nicht, was Sie wollen. Wenn Sie jedoch C möchten, gibt es die
rand()
undsrand()
-Funktionen:Diese sind beide Teil von ANSI C. Es gibt auch die
random()
Funktion:Aber soweit ich das beurteilen kann,
random()
handelt es sich nicht um Standard-ANSI C. Eine Bibliothek von Drittanbietern ist möglicherweise keine schlechte Idee, aber alles hängt davon ab, wie zufällig eine Zahl ist, die Sie wirklich generieren müssen.quelle
C Programm zur Erzeugung einer Zufallszahl zwischen 9 und 50
Im Allgemeinen können wir eine Zufallszahl zwischen LowerLimit und UpperLimit-1 generieren
dh LowerLimit ist inklusive oder sagt r ∈ [LowerLimit, UpperLimit)
quelle
rand()
ist der bequemste Weg, um Zufallszahlen zu generieren.Sie können auch Zufallszahlen von jedem Onlinedienst wie random.org abrufen.
quelle
quelle
quelle
Auf modernen x86_64-CPUs können Sie den Hardware-Zufallszahlengenerator über verwenden
_rdrand64_step()
Beispielcode:
quelle
quelle
Als
rand()
ich eine gute Erklärung hörte, warum es eine schlechte Idee ist, gleichmäßig verteilte Zufallszahlen in einem bestimmten Bereich zu erzeugen, beschloss ich, einen Blick darauf zu werfen, wie verzerrt die Ausgabe tatsächlich ist. Mein Testfall war faires Würfeln. Hier ist der C-Code:und hier ist seine Ausgabe:
Ich weiß nicht, wie einheitlich Ihre Zufallszahlen sein müssen, aber das Obige scheint für die meisten Anforderungen einheitlich genug zu sein.
Bearbeiten: Es wäre eine gute Idee, das PRNG mit etwas Besserem als zu initialisieren
time(NULL)
.quelle
Ich hatte in meiner letzten Anwendung ein ernstes Problem mit dem Pseudozufallszahlengenerator: Ich habe mein C-Programm wiederholt über ein Pyhton-Skript aufgerufen und den folgenden Code als Startwert verwendet:
Da jedoch:
man srand
);time
wird wird jedes Mal derselbe Wert zurückgegeben.Mein Programm hat die gleiche Zahlenfolge generiert. Sie können drei Dinge tun, um dieses Problem zu lösen:
Mischzeitausgabe mit einigen anderen Informationen, die sich bei Läufen ändern (in meiner Anwendung der Ausgabename):
Ich habe djb2 als Hash-Funktion verwendet.
Erhöhen Sie die Zeitauflösung. Auf meiner Plattform
clock_gettime
war verfügbar, also benutze ich es:Verwenden Sie beide Methoden zusammen:
Option 3 stellt sicher, dass Sie (soweit ich weiß) die beste Zufalls-Zufälligkeit haben, kann jedoch nur bei sehr schneller Anwendung einen Unterschied bewirken. Meiner Meinung nach ist Option 2 eine sichere Wette.
quelle
rand()
sollte nicht für kryptografische Daten verwendet werden, stimme ich zu. Zumindest für mich enthielt meine Anwendung keine kryptografischen Daten, daher war die angegebene Methode für mich in Ordnung.Trotz aller Vorschläge der Leute
rand()
hier möchten Sie nicht verwenden, esrand()
sei denn, Sie müssen! Die Zufallszahlen, dierand()
erzeugt werden sind oft sehr schlecht. Um aus der Linux-Manpage zu zitieren:In Bezug auf die Portabilität
random()
wird dies seit geraumer Zeit auch vom POSIX-Standard definiert.rand()
älter ist, erschien es bereits in der ersten POSIX.1-Spezifikation (IEEE Std 1003.1-1988), wohingegenrandom()
zuerst in POSIX.1-2001 (IEEE Std 1003.1-2001) erschien, der aktuelle POSIX-Standard ist jedoch bereits POSIX.1-2008 (IEEE Std 1003.1-2008), die vor einem Jahr ein Update erhalten hat (IEEE Std 1003.1-2008, Ausgabe 2016). Daher würde ich es alsrandom()
sehr tragbar betrachten.POSIX.1-2001 führte auch die Funktionen
lrand48()
und einmrand48()
, siehe hier :Und eine ziemlich gute Pseudozufallsquelle ist die
arc4random()
Funktion, die auf vielen Systemen verfügbar ist. Nicht Teil eines offiziellen Standards, erschien um 1997 in BSD, aber Sie können ihn auf Systemen wie Linux und macOS / iOS finden.quelle
random()
existiert unter Windows nicht.rand()
da dies auch vom C-Standard verlangt wird. Für alles andere benötigen Sie wie gewohnt nur eine spezielle Lösung für Windows.#ifdef _WIN32
ist der Ausdruck, den Sie am häufigsten in plattformübergreifendem Code sehen, der Windows unterstützen möchte. In der Regel gibt es eine Lösung, die mit allen Systemen funktioniert, und eine, die nur für Windows erforderlich ist.Für Linux C-Anwendungen:
Dies ist mein überarbeiteter Code aus einer Antwort oben, die meinen C-Code-Praktiken folgt und einen zufälligen Puffer beliebiger Größe (mit geeigneten Rückkehrcodes usw.) zurückgibt. Stellen Sie sicher, dass Sie zu
urandom_open()
Beginn Ihres Programms einmal aufrufen .quelle
Meine minimalistische Lösung sollte für Zufallszahlen im Bereich funktionieren
[min, max)
. Verwenden Sie diesesrand(time(NULL))
Option, bevor Sie die Funktion aufrufen.quelle
Versuchen Sie dies, ich habe es aus einigen der Konzepte zusammengestellt, auf die oben bereits verwiesen wurde:
quelle
srand()
jedes Mal anzurufen, wenn Sie anrufen möchtenrand()
. Datime()
normalerweise ein Wert in Sekunden zurückgegeben wird , gibt das schnelle Aufrufen dieser Funktion denselben "zufälligen" Wert zurück.random()
Funktion verwechselt .