Zufallszahlen rand() vs /dev/urandom



  • Hallo,

    ich weiß das rand() sowohl als auch /dev/urandom keine echten Zufallszahlen liefern. Der Vorteil von rand ist, es ist in der C Bibliothek integriert und somit wäre der Code plattformunabhängig im Gegensatz zum Auslesen von /dev/urandom, welches nur unter UNIX Systemen verfügbar ist.

    Ich möchte wissen ist rand() von der Güte gleichwertig wie /dev/urandom ?

    Vielen Dank im Voraus



  • Die vmtl. ausführlichste Antwort hierzu:
    http://www.2uo.de/myths-about-urandom/



  • Matrix8974 schrieb:

    Ich möchte wissen ist rand() von der Güte gleichwertig wie /dev/urandom ?

    rand ist falsch benannt, weil es tatsächlich nicht das geringste mit Zufall zu tun hat. Es liefert eine sehr kurze Folge von nicht-gleichverteilten Zahlen, die auf den ersten Blick für einen Menschen "zufällig aussehen".Typischerweise sind das bei jeder Instanz des Programms die gleichen Zahlen. Es gibt keinen Grund so etwas zu verwenden. Aus Sicherheitsgründen sollte die Funktion meiner Meinung nach deprecated sein, weil sie ständig mit einem Zufallsgenerator verwechselt wird.

    Mal zur Verdeutlichung eine standardkonforme* Implementierung von rand :

    static size_t next = 0; //globale, ungeschütze Variable -> nicht einmal threadsafe
    
    void srand(int seed)
    {
    	next = (size_t)seed;
    }
    
    int rand(void)
    {
    	static int const numbers[] = {5, 4234, 54858, 122, 38586, /*...*/};
    	if (next >= (sizeof(numbers) / sizeof(*numbers)))
    	{
    		next = 0;
    	}
    	return numbers[next++];
    }
    

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe



  • TyRoXx schrieb:

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe

    Du übertreibst.



  • volkard schrieb:

    TyRoXx schrieb:

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe

    Du übertreibst.

    Womit?



  • TyRoXx schrieb:

    Matrix8974 schrieb:

    Ich möchte wissen ist rand() von der Güte gleichwertig wie /dev/urandom ?

    rand ist falsch benannt, weil es tatsächlich nicht das geringste mit Zufall zu tun hat. Es liefert eine sehr kurze Folge von nicht-gleichverteilten Zahlen, die auf den ersten Blick für einen Menschen "zufällig aussehen". Es gibt keinen Grund so etwas zu verwenden. Aus Sicherheitsgründen sollte die Funktion meiner Meinung nach deprecated sein, weil sie ständig mit einem Zufallsgenerator verwechselt wird.

    Mal zur Verdeutlichung eine standardkonforme* Implementierung von rand :

    static size_t next = 0; //globale, ungeschütze Variable -> nicht einmal threadsafe
    
    void srand(int seed)
    {
    	next = (size_t)seed;
    }
    
    int rand(void)
    {
    	static int const numbers[] = {5, 4234, 54858, 122, 38586, /*...*/};
    	if (next >= (sizeof(numbers) / sizeof(*numbers)))
    	{
    		next = 0;
    	}
    	return numbers[next++];
    }
    

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe

    damit



  • Matrix8974 schrieb:

    Ich möchte wissen ist rand() von der Güte gleichwertig wie /dev/urandom ?

    Der wichtigste Unterschied ist, dass /dev/urandom ein CSPRNG sein sollte - also für kryptografische Anwendungen geeignet ist. Das trifft auf die gängigen libc-Generatoren (rand(3), random(3), drand48(3) mit Ausnahme von arc4random(3) unter BSD) nicht zu. Das Anwendungsgebiet ist also ein völlig anderes.



  • TyRoXx schrieb:

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe

    Erinnert an:
    http://xkcd.com/221/

    😃



  • oenone schrieb:

    TyRoXx schrieb:

    * verbessert mich bitte, wenn ich etwas falsch gemacht habe

    Erinnert an:
    http://xkcd.com/221/

    😃

    Das wäre eine standardkonforme Implementierung. Das kann man nachlesen:

    C Committee Draft 2007-09-07 schrieb:

    The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX.
    The implementation shall behave as if no library function calls the rand function.
    The rand function returns a pseudo-random integer.
    The value of the RAND_MAX macro shall be at least 32767.

    Das ist alles, was C von rand verlangt. Dies erfüllt alle Bedingungen:

    int rand(void)
    {
        return 4; //if not random enough, change 4 into 7
    }
    

    Aber ich übertreibe ja bloß...



  • Auf welchem Planeten ist das Pseudo-Zufall?



  • Bashar schrieb:

    Auf welchem Planeten ist das Pseudo-Zufall?

    Auf allen, die die Bedeutung von "Pseudo" kennen.



  • oenone schrieb:

    Bashar schrieb:

    Auf welchem Planeten ist das Pseudo-Zufall?

    Auf allen, die die Bedeutung von "Pseudo" kennen.

    Dir kann geholfen werden. http://de.wiktionary.org/wiki/pseudo-
    Bedeutungen:
    [1] falsch, unecht, vorgetäuscht
    Herkunft:
    [1] analoge Wortbildungen wie in griech. Vorbildern, z. B.: ψευδοπροφήτης (pseudoprophētēs) „falscher Prophet“, diese gehen zurück auf ψευδής (pseudēs) „falsch, lügenhaft“, ψεῦδος (pseudos) „Täuschung, Lüge“

    Das return 4; versucht ja nichtmal, Zufall vorzutäuschen und ist damit raus.





  • Bashar schrieb:

    de.wikipedia.org/wiki/Pseudozufall
    🙄

    Wikipedia schrieb:

    In der Berechenbarkeitstheorie wird alles das als pseudozufällig bezeichnet, was aus der Perspektive des Betrachters nicht von wirklicher Zufälligkeit unterschieden werden kann.

    Ich kann gar nichts von Zufälligkeit unterscheiden, wenn ich es nur von außen betrachte. Oder ist eine Münze, die zwanzig mal hintereinander Kopf zeigt, dann automatisch keine Münze mehr? Fällt sie danach auf Zahl, damit ihr Verhalten "zufällig" ist?

    volkard schrieb:

    Das return 4; versucht ja nichtmal, Zufall vorzutäuschen und ist damit raus.

    Wo steht im C-Standard, dass die Sequenz glaubwürdig sein muss? Wo steht überhaupt, dass die Periode eine bestimmte Länge haben muss? Ein Pseudozufallsgenerator mit der Periode eins liefert eben immer die gleiche Zahl. 4, 4, 4, 4, 4, 4, 4, 4 kann ich auch würfeln, also warum darf rand das nicht zurückgeben?

    static int next = 0;
    int rand(void)
    {
    	if (next >= RAND_MAX)
    	{
    		next = 0;
    	}
    	return next++;
    }
    

    Ist das "zufällig" genug? Wo ist die Grenze? Warum war meine Implementierung mit dem konstanten Array "übertrieben"?



  • TyRoXx schrieb:

    Bashar schrieb:

    de.wikipedia.org/wiki/Pseudozufall
    🙄

    Wikipedia schrieb:

    In der Berechenbarkeitstheorie wird alles das als pseudozufällig bezeichnet, was aus der Perspektive des Betrachters nicht von wirklicher Zufälligkeit unterschieden werden kann.

    Ich kann gar nichts von Zufälligkeit unterscheiden, wenn ich es nur von außen betrachte.

    Dann lass es einen Hauptschüler mal probieren! Der wird es sauber entscheiden können in unserem Sinne.



  • TyRoXx schrieb:

    Wo steht im C-Standard, dass die Sequenz glaubwürdig sein muss? Wo steht überhaupt, dass die Periode eine bestimmte Länge haben muss? Ein Pseudozufallsgenerator mit der Periode eins liefert eben immer die gleiche Zahl. 4, 4, 4, 4, 4, 4, 4, 4 kann ich auch würfeln, also warum darf rand das nicht zurückgeben?

    Genau auf der Seite, wo steht, daß die Multiplikation zweier ints nicht länger als eine Million Stunden dauert. Würde ich mich jetzt so bekloppt wie Du anstellen, müßte ich a*b meiden. Besser noch: Ich würde verlangen, den *-Operator ganz abzuschaffen.

    TyRoXx schrieb:

    static int next = 0;
    int rand(void)
    {
    	if (next >= RAND_MAX)
    	{
    		next = 0;
    	}
    	return next++;
    }
    

    Ist das "zufällig" genug? Wo ist die Grenze? Warum war meine Implementierung mit dem konstanten Array "übertrieben"?

    Keine Lust, gegen jemanden zu argumentieren, der sich absichtlich doof stellt.


Anmelden zum Antworten