2016-07-28 3 views
1

Zum Beispiel:ist ein Stapelzeiger eine gute Quelle für Pseudozufallszahl

int main() 
{ 
    int p; 

    ::std::cout << ::std::uintptr_t(&p) << ::std::endl; 
} 

Dies wird produzieren konsequent „random“ Zahlen, wenn wiederholt ausgeführt. Etwas Ähnliches könnte in C erreicht werden. Ich sehe nichts UB darüber.

+4

es ist nicht UB, aber was ist der Grad der Zufälligkeit? Wer garantiert es? –

+0

Die Antwort für einen Titel: Nein. Gibt es UB? Ja, da der Wert, den Sie erhalten, nicht definiert ist. Es könnte sehr gut immer 133 sein. –

+4

Ich bin nicht derzeiger der Zeiger. – user1095108

Antwort

4

Ich bin ganz abhängig von den Anforderungen, die Sie auf die Verteilung der Zufallszahlen festgelegt haben. Ist die Reihenfolge 1,1,1,1,1,1,1 zufällig? Eigentlich schwer zu sagen, aber wenn Sie einen Test für eine normale Verteilung machen, wird es sicherlich fehlschlagen. Pseudozufallszahlengeneratoren wurden speziell entwickelt, um die Eigenschaften der Zufallsverteilung zu ermitteln, die Sie von ihnen erhalten möchten.

Wenn Sie ein paar Tricks machen, um eine vorher unbekannte Nummer zu bekommen (absichtlich nenne ich das nicht zufällig), erscheint Ihnen diese Zahl zufällig, aber es ist sehr wahrscheinlich, dass es Muster gibt, die Sie nicht entdecken.

TL; DR: es ist nicht einfach, einen guten Rng zu schreiben. Verwenden Sie diejenigen, die verfügbar sind, wenn Sie Zufallszahlen benötigen.

+0

Mmmm, wie wäre es mit dem Stack-Zeiger als Samen zu einem "richtigen" Pseudo-RNG? – user1095108

+6

Dieser Ausschnitt in einigen Umgebungen gibt nur den gleichen Wert zurück * always *. Es ist eine ** BAD ** Entropie-Quelle, egal wie Sie es nennen. –

+2

@ user1095108 dann haben Sie eine schlechte Qualität Samen, die den Punkt der Verwendung eines Rng in erster Linie – user463035818

3
  • Als Quelle für Zufallszahl auf seinem eigenen, es ist ziemlich schlecht, weil es für einen ernsthaften Gegner sehr vorhersehbar sein wird. Wie andere gesagt haben, ist der Adressraum begrenzt, die Adressen, die die Ausrichtungsanforderungen für eine int erfüllen, sind viel weniger und darüber hinaus der Algorithmus, mit dem Ihr Programm in den Speicher geladen wird, wenn es nicht dokumentiert ist, ist es zumindest nicht für viel Zufall gebaut.
  • Als eine Quelle von Entropie, hängt es vom Betriebssystem ab. Wenn das Betriebssystem nicht zufälligt, wird es die Lesbarkeit beeinträchtigen - weil jemand, der Ihren Code liest, fälschlicherweise denkt, dass Sie an diesem Punkt Entropie hinzufügen. Wenn das Betriebssystem randomisiert, wird es immer noch keine große Quelle der Entropie sein, und Sie müssten es mit anderen besseren Quellen kombinieren, um zu kompensieren - und diese müssen völlig unabhängig von der Entropiequelle der zufälligen Adresse sein.

In jedem Fall ist das alles vorausgesetzt, Sie die Adresse verwenden der Variablen (perfekt gültig) und nicht sein Wert (nicht definiertes Verhalten, wenn nicht initialisierte). Wenn Sie ein undefiniertes Verhalten aufrufen, kann die Operation Ihre gesamte Entropie wegwerfen.

+1

Nun, die Quelle der Entropie liegt wirklich nur im Speicherlayout, also ohne Adressrandomisierung ist es 0 Bit Entropie, also ja, indem man keine Entropie hinzufügt, sondern diese Tatsache verschleiert, würde es * wehtun, und wenn es eine Adress-Radnomisierung gibt , Sie sollten die Quelle der Entropie verwenden, um das zu erzeugen - sonst würden Sie wieder Entropie verschwenden. Meine Vermutung ist, dass Betriebssysteme mit ASLR die gleiche Entropiequelle bei der Initialisierung verwenden, wie sie als Zufallsgerät verfügbar ist, z. B./dev/random, und Ihnen dann eine RNG-Sequenz geben, die * Entropie * nicht hinzufügt, wenn Sie abziehen können der ursprüngliche Samen. –

+2

Also, ja, ich denke, es sollte nicht getan werden, weil es die Tatsache verschleiert, dass es nicht hilft. –

+0

@ MarcusMüller Guter Punkt. –

4

Nein, nein, nein.

Sie können nicht Variablenadressen, Werte von nicht initialisierten Variablen und dergleichen als Quellen von Zufallszahlen.

Einige dieser Anwendungen werden Sie verdienen ein Ticket direkt auf „undefiniert Verhalten Land“, wo Ihr Compiler schrecklich, erlaubt ist schrecklich Dinge, um Ihren Code zu tun.

Einige sind nur nicht wirklich all das zufällig.

Wenn Sie Zufallszahlen möchten, verwenden, was in < random vorgesehen ist> und stellen Sie sicher, dass Sie Ihren Generator richtig Samen, wenn Sie nicht random_device direkt verwenden (was Sie wahrscheinlich für Nicht-Krypto sichere Zahlen nicht wollen).

Und nicht einmal rand() betrachten - vergessen sie existiert. Es ist furchtbar.

sollten Sie eine std::seed_seq verwenden mehrere Entropie Quellen zu mischen und dann, dass der Generator auf Saatgut verwenden. Unter der Adresse einer Variablen als eines von vielen Eingängen für seed_seq wäre ok, vorausgesetzt, Sie auch andere Quellen von höherer Qualität (insbesondere std::random_device) umfassen.

+1

Als Kommentar, der den Punkt Ihrer Antworten betont: ** Nein, es ist keine gute Quelle **. –

+1

Außerdem ist es eine schlechte Quelle. ** Sowie es nicht gut ist. Oder es als eine Quelle der Zufälligkeit zu verwenden, die ein falscher Ansatz ist. Oder tatsächlich ist der Gedanke, dass die Adresse einer Variablen zufällig ist, falsch. Ich habe keine Möglichkeiten mehr, dies zu tun. –

+0

Ihr habt natürlich beide recht. Deshalb habe ich gesagt, dass es nur als Teil eines 'seed_seq's in Ordnung ist, wo Sie auch mehrere andere Quellen höherer Qualität hinzufügen. In diesem Fall wird es nicht weh tun - aber auch nicht viel helfen ... –

4

Wenn Ihr OS randomizes the stack address of your program, können Sie mehrere zufällige Bits von der Adresse Ihrer lokalen Variablen extrahieren. Diese werden wahrscheinlich hochwertige Zufallsbits (wenn Ihr Betriebssystem ist gut), aber es wird nur wenige, denn:

  • gibt es strenge Anforderungen an die Ausrichtung (so die niedrigen Bits wird konstant, nicht zufällig also diese Methode nicht gut ist, weil das Ergebnis stark auf O setzt konstant)

sein)

  • jedes Betriebssystem schränkt wahrscheinlich den Adressraum von Anwenderprogrammen aus praktischen Gründen (so wird der High-Bits (als ein extremes Beispiel , ein Benutzer kann ASLR deaktivieren, und Ihr Zufallsgenerator wird für diesen Benutzer nicht mehr funktionieren).

  • +0

    Und auch statt mit derselben Zufälligkeit, die die ASLR verwendet, verwenden Sie ein eingeschränktes, teilweise bestimmbares Ergebnis dieser Zufälligkeit. Verwenden Sie einfach die zufällige Quelle Ihres Systems; Unixoids haben normalerweise/dev/random, das ziemlich gut als Quelle der Entropie funktioniert. –

    Verwandte Themen