Zufällig ohne Zeitbasis [geschlossen]

9

Computer erstellen nicht aus dem Nichts Zufallszahlen ohne Basis, da Zeit höchstwahrscheinlich die universelle Basis für Zufälligkeit ist.

Ich möchte, dass Sie einen Code erstellen, der Zufallszahlen mit folgenden Regeln erstellt:

  • Zeit darf zu keinem Zeitpunkt des Programms die Grundlage sein.
  • Vordefinierte Zufalls- / Pseudozufallsfunktionen sind nicht zulässig.
  • Die generierten Zahlen können in einem beliebigen Bereich liegen. Nun, mindestens zwei verschiedene ganze Zahlen: D.
  • Zahlen werden wiedergegeben.
Dadan
quelle
2
Es ist unklar, was Sie unter "Generierte Zahlen können in einem beliebigen Bereich liegen" verstehen. Meinen Sie, der Codierer kann einen Bereich frei wählen? Oder dass sie jeden Bereich unterstützen müssen, den der Benutzer anfordert? Beides ist problematisch. Wenn der Benutzer einen Bereich anfordert, was ist, wenn er Nummern außerhalb der Grenzen der integrierten Datentypen anfordert? Und wenn der Codierer frei wählen kann, wähle ich ganze Zahlen zwischen 1 und 1 .: D
Jonathan Van Matre
2
Sollte ein Code-Golf gewesen sein ...
Mukul Kumar
Ich habe diese Frage als Beliebtheitsfrage begonnen. Würde Code-Golf besser dazu passen?
Dadan
@ Daniel Ja, aber lassen Sie diese Frage Popularität-Frage sein und posten Sie eine neue Frage mit Code Golf mit neuen Regeln (auf zufällige Generation), die Spaß machen wird
Mukul Kumar
1
Das Internet als Keim zu benutzen scheint zu schummeln, nicht wahr?
Dean MacGregor

Antworten:

6

JavaScript

Das hat Spaß gemacht!

arr = []
index = 0

function init(seed) {
    index = 0
    arr[0] = seed
    for (var i = 1; i < 624; i ++) {
        arr[i] = (1812433253 * (arr[i-1] ^ (arr[i-1] >>> 30)) + i) | 0
    }
 }

function getNumber() {
    if (index == 0) generateNumbers()

    var y = arr[index]
    y ^= (y >>> 11)
    y ^= ((y << 7) & 2636928640)
    y ^= ((y << 15) & 4022730752)
    y ^= (y >>> 18)

    index = (index + 1) % 624
    return y
}

function generateNumbers() {
    for (var i = 0; i < 624; i ++) {
        var y = (arr[i] & 0x80000000) + (arr[(i+1) % 624] & 0x7fffffff)
        arr[i] = arr[(i + 397) % 624] ^ (y >>> 1)
        if (y % 2 != 0) arr[i] ^= 2567483615
    }
}

// let's get our seed now from the SE API
var x = new XMLHttpRequest()
x.open('GET', 'http://api.stackexchange.com/2.2/answers?pagesize=10&order=desc&sort=activity&site=stackoverflow&filter=!Sri2UzKb5mTfr.XgjE', false)
x.send(null)
// we've got the answer data, now just add up all the numbers.
// only 4 digits at a time to prevent too big of a number.
var seed = 0
var numbers = x.responseText.match(/\d{0,4}/g)
for (var i = 0; i < numbers.length; i++) seed += +numbers[i]

init(seed)
for (var i = 0; i < 10; i++) console.log(getNumber())

Ich habe den Mersenne Twister in JS geschrieben. Dann wurde mir klar, dass ich irgendwo einen Samen bekommen musste.

Also habe ich beschlossen, es von der Stack Exchange API zu bekommen! (Ich könnte localStorageeinen Zähler verwenden und erhöhen, aber das macht keinen Spaß.) Also habe ich die 10 zuletzt aktiven Antworten abgerufen und dann alle 4 oder weniger aufeinander folgenden Ziffern in der Antwort genommen und sie addiert.

Diese Seeds sind immer unterschiedlich, da der Stapelüberlauf ständig aktualisiert wird (und mein Kontingent weiter sinkt!). Die Zahlen umfassen Antwort-IDs, Fragen-IDs, Punktzahlen, Anzahl der Up- / Downvotes, Repräsentanten / IDs der Eigentümer und die Wrapper-Daten (Kontingent und dergleichen) ). Bei einem Lauf bekam ich 256845dann 270495und dann 256048etc ....

Dadurch werden 10 zufällige 32-Bit-Zweierkomplementzahlen in der Konsole protokolliert. Beispielausgabe:

247701962
-601555287
1363363842
-1184801866
1761791937
-163544156
2021774189
2140443959
1764173996
-1176627822
Türknauf
quelle
5

Java

import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

/**
 *
 * @author Quincunx
 */
public class NoTimeRandom extends Random {

    private AtomicLong seed;

    public NoTimeRandom() {
        byte[] ba = (new String[0].toString() + new String[0].toString()
                + new String[0].toString() + new String[0].toString()
                + new String[0].toString() + new String[0].toString()).getBytes();
        int seed1 = 1;
        for (byte b : ba) {
            seed1 += b;
        }

        ba = (new String[0].toString() + new String[0].toString()
                + new String[0].toString() + new String[0].toString()
                + new String[0].toString() + new String[0].toString()).getBytes();
        long seed2 = 1;
        for (byte b : ba) {
            seed2 += b;
        }

        seed = new AtomicLong(seed1 ^ seed2);
    }

    @Override
    protected int next(int bits) {
        long oldseed, newseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            newseed = (oldseed * 25214903917L + 11) & 281474976710655L;
        } while (!seed.compareAndSet(oldseed, newseed));

        return (int) (newseed >>> (48 - bits));
    }

    public static void main(String[] args) {
        Random r = new NoTimeRandom();

        for (int i = 0; i < 5; i++) {
            System.out.println(r.nextInt());
        }
    }

}

Die Magie liegt in der public NoTimeRandom(). In Strings gegossene Arrays können neue Programmierer verwirren, da die Zahlen zufällig sind. Probe (für char[]: [C@4a8e91eb). Die nextMethode wird kopiert von java.util.Random.

Beispielausgabe:

134277366
467041052
-555611140
-1741034686
1420784423

Lassen Sie uns die Wirksamkeit dieses Rng testen:

In meiner Antwort auf Approximate a Bell Curve hängt die von mir verwendete Datengenerierung von einem guten Rng ab. Lassen Sie es uns als rng ausführen. Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Genau wie ich gedacht habe. Das ist eine ziemlich miese Sache.

Justin
quelle
5

C.

Kompilieren Sie mit dem Flag -pthread (oder was auch immer Ihr Compiler verwendet).

#include <stdio.h>
#include <pthread.h>

#define m (unsigned long)2147483647
#define q (unsigned long)127773
#define a (unsigned int)16807
#define r (unsigned int)2836 

static unsigned long seed;
pthread_t t[20];
int lo, hi, done;

void *pseudorandom(void *id)
{
    while(done)
    {
        int test;
        hi = seed/q;
        lo = seed%q;
        test = a * lo - r * hi;
        if (test > 0) seed = test;
        else seed = test + m;
    }
}

main()
{
     int i;
     seed = 54321;
     done = 1;

     for(i = 0; i < 20; i++) 
     {
          pthread_create(&(t[i]), NULL, &pseudorandom, NULL);
     }

     for (i = 0; i < 10; i++) 
     {
          printf("%lu\n", seed);
     }

     done = 0;
}

Ich bin mir nicht sicher, ob dies aufgrund des Standards "Zeit ist nicht zulässig" qualifiziert ist oder nicht, da der Scheduler im Grunde genommen als Entropiequelle verwendet wird, indem die Thread-Sicherheit absichtlich ignoriert wird. Es funktioniert mit einer ziemlich einfachen Pseudozufallsfunktion ( Lehmer-Zufallszahlengenerator ) mit einem hartcodierten Anfangssamen. Anschließend werden 20 Threads gestartet, die alle die Lehmer-Berechnung mit einem gemeinsamen Satz von Variablen ausführen.

Scheint ziemlich gut zu funktionieren, hier sind ein paar aufeinanderfolgende Läufe:

comintern ~ $ ./a.out
821551271
198866223
670412515
4292256
561301260
1256197345
959764614
874838892
1375885882
1788849800
comintern ~ $ ./a.out
2067099631
953349057
1736873858
267798474
941322622
564797842
157852857
1263164394
399068484
2077423336

EDIT: Hab mir ein bisschen mehr Gedanken gemacht und festgestellt, dass dies überhaupt nicht zeitbasiert ist. Selbst mit einem vollständig deterministischen Scheduler kommt die Entropie nicht aus den Zeitscheiben, sondern aus dem Laden aller laufenden Prozesse auf dem System.

BEARBEITEN 2 Nachdem ich mich von @Quincunx inspirieren ließ, eine Glockenkurve zu veröffentlichen, habe ich 12 MB Zufälligkeit in eine Datei kopiert und auf CAcert hochgeladen . Es hat alle eingefleischten Tests nicht bestanden, aber beim HNO-Test respektable 7,999573 von 8 erreicht (nur potenziell deterministisch). Seltsamerweise machte es die Verdoppelung der Fadenzahl noch schlimmer.

Komintern
quelle
4

C.

Es generiert eine Zufallszahl im Bereich von 0 bis 255, indem der Startwert von https://stackoverflow.com/questions verwendet wird wget.

#include <stdio.h>
main()
{
    FILE *file;
    unsigned char c,x;
    system("wget -O - https://stackoverflow.com/questions > quest.html");
    file = fopen ("quest.html", "r");
    while(c=fgetc(file) != EOF) x+=c;
    fclose(file);
    printf("%d",x);
}

Probelauf:

C:\Users\izabera>random
--2014-03-02 16:15:28--  https://stackoverflow.com/questions
Resolving stackoverflow.com... 198.252.206.140
Connecting to stackoverflow.com|198.252.206.140|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 85775 (84K) [text/html]
Saving to: `STDOUT'

100%[======================================>] 85,775      40.3K/s   in 2.1s

2014-03-02 16:15:31 (40.3 KB/s) - `-' saved [85775/85775]

15 /* <=================== THIS IS THE RANDOM NUMBER */
C:\Users\izabera>random
--2014-03-02 16:15:36--  https://stackoverflow.com/questions
Resolving stackoverflow.com... 198.252.206.140
Connecting to stackoverflow.com|198.252.206.140|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 85836 (84K) [text/html]
Saving to: `STDOUT'

100%[======================================>] 85,836      50.0K/s   in 1.7s

2014-03-02 16:15:38 (50.0 KB/s) - `-' saved [85836/85836]

76
C:\Users\izabera>random
--2014-03-02 16:15:56--  https://stackoverflow.com/questions
Resolving stackoverflow.com... 198.252.206.140
Connecting to stackoverflow.com|198.252.206.140|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 85244 (83K) [text/html]
Saving to: `STDOUT'

100%[======================================>] 85,244      36.0K/s   in 2.3s

2014-03-02 16:15:59 (36.0 KB/s) - `-' saved [85244/85244]

144
Izabera
quelle
2

C ++

#include<iostream>
int main()
{
    int *ptr=new int,i=0;
    for(;i<5;i++)
    {
        std::cout<<*(ptr+i)<<'\n';
    }
    return 0;
}  

Ausgabe

5 beliebige Zufallszahlen

drei Proben
Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Mukul Kumar
quelle
1
1., 2. und 5. sind ziemlich nahe beieinander, dasselbe Muster wiederholt sich in allen drei Beispielen. nicht genau die erwartete Ausgabe von einem Zufallszahlengenerator.
Izabera
@izabera Wenn es um Zeiger beim Generieren von Zufallszahlen geht ... hängt alles von Ihrem Computer ab (RAM und Prozessor), möglicherweise wird derzeit die Adresse verwendet, die von 'new int' in 'ptr' eingegeben wird! Sie haben versucht, diesen Code auszuführen?
Mukul Kumar
Lassen Sie mich eine kleine Änderung hinzufügen
Mukul Kumar
Ich habe es jetzt versucht, auf meinem Computer scheint es, als ob ich immer Dinge bekomme 11230576, 0, 11206992, 0, 2053725299, die mir immer noch nicht zufällig erscheinen.
Izabera
check it out at ideone
izabera
2

Perl

Was ist das für ein Müll, wenn man Samen über das Internet bekommt? Klingt für mich nach Betrug ;-) Ich bevorzuge es, meinen Startwert stattdessen einer kryptografischen Hash-Funktion zu geben und eine Ausgabe im Bereich von 0 bis 2 ^ 160-1 wie folgt zu geben:

use Digest::SHA1 qw(sha1);
use bigint;
sub r {
  $_ = \3;
  /^.*x([0-9a-f]+).$/;
  hex((unpack "H*", sha1 "some_salt".$1.$$)[0])
}
print join " ", r'

Immer wenn Sie eine Entropie von ungewisser Qualität haben, können Sie sie regelmäßiger verteilen (aber nicht verbessern!), Indem Sie sie in SHA1 oder MD5 oder so weiterleiten, wie ich es hier getan habe. Für Pre-Hash-Samen habe ich pid und die Adresse einer zufälligen Referenz verwendet. Sie können natürlich auch andere Eingaben für mehr Entropie hinzufügen, z. B. auf x86 können Sie TSC verwenden - (aber das Inlinen von Assembly-Code in Perl ist ein bisschen bärig, also habe ich ihn übersprungen).

Wenn Sie eine andere Ausgabe als der Typ auf dem nächsten Computer haben möchten, passen Sie einfach "some_salt" an, um eine Zeichenfolge zu werden, die Ihnen gefällt. Oder lassen Sie es ganz weg, wenn Sie ein Minimalist sind =)

skibrianski
quelle
Ich würde vermuten, dass jede kryptografische Funktion, die ihren Namen in einer Standardbibliothek verdient, intern ein kryptografisch sicheres RNG verwendet.
Duci9y
Da bin ich mir nicht sicher. Digest :: MD5 / Digest :: SHA1 erzeugen eine vollständig deterministische, wiederholbare Ausgabe. Wofür benötigt es also eine Zufallszahl?
Skibrianski
Es tut uns leid! Ich bin nur über Ihre Antwort geflogen und dachte, dass Sie einen Schlüssel anstelle eines Digests generieren.
Duci9y
2

Java

Meine Lösung Verletzungen hashCode()Methode der ObjectKlasse.

class G22640 {
    static class Rand {
        public int nextInt() {
            return new Object().hashCode();
        }
    }

    public static void main(String args[]) {
        Rand r = new Rand();
        for (int i = 0; i < 10; i++) {
            System.out.println(r.nextInt());
        }
    }
}

Beispielausgabe:

31859448
22101035
11593610
4580332
25736626
32157998
3804398
32440180
19905449
2772678

Motiviert durch andere Antworten, die die Zufälligkeit der Lösung demonstrieren, habe ich meine Lösung geändert, um die mittleren 16 Bits der intzurückgegebenen von zurückzugeben Object.hashCode().

import java.io.*;

class G22640 {
    static class Rand {
        public short nextShort() {
            return (short) ((new Object().hashCode() >> 8) & 0xFFFF);
        }
    }

    public static void main(String args[]) throws IOException {
        Rand r = new Rand();

        for (int i = 0; i < 10; i++) {
            System.out.println(r.nextShort());
        }

        // generateToFile("random_22640.txt");
    }

    private static void generateToFile(String fileName) throws IOException {
        Rand r = new Rand();
        BufferedOutputStream o = new BufferedOutputStream(new FileOutputStream(fileName));

        for (int i = 0; i < 10000000; i++) {
            int a = r.nextShort();
            for (int j = 0; j < 2; j++) {
                o.write(a & 0xFF);
                a >>= 8;
            }
        }

        o.flush();
        o.close();
    }
}

Ich habe eine 19-MB-Datei (bestehend aus 10 7 short ) erstellt und an CACert gesendet . Hier ist der Screenshot des Ergebnisses (es wurde bearbeitet, um gut auszusehen, aber die Zahlen bleiben unverändert):

Ergebnis

Ich war überrascht über das Ergebnis, da es beim Entropietest 7.999991 taktet und alle 7 Diehard-Tests (?) Besteht.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
quelle
2

Javascript
Zufälliges Generieren mit der Mausbewegung des Benutzers

var ranArr=[];
var random=0;
var first=second=0;
function generateR(event) {
ranArr.push(parseFloat(event.clientX+document.body.scrollLeft))
ranArr.push(parseFloat(event.clientY+document.body.scrollTop));
var len=ranArr.length;

for(var i=0;i<len;i++) {
    if(i<len/2) {

    first+=ranArr[i];
    } else {
    second += ranArr[i];
    }
}
third = second/first;
third = third+"";
console.log(third.substr(5));
}
document.onmousemove=function(event){generateR(event)};

Die letzten fünf kopierten Daten:
9637090187003
7828470680762
6045869361238
4220720695015
2422653391073

vusan
quelle
1

Bash, Bereich: Ints zwischen 0 und 1

echo -n & echo "$! % 2" | bc
Keba
quelle
Du meinst also, es wählt nur 0 oder 1?
Ja. Sollte erfüllen "Generierte Zahlen können in einem beliebigen Bereich liegen. Nun, mindestens zwei verschiedene ganze Zahlen: D", nicht wahr?
Keba
Ich denke schon. Denken Sie, Sie könnten es auf ein größeres Sortiment erweitern?
Ich echo -n & echo $!werde es einfach tun, aber ein sehr schlechtes RNG sein. Sie können 2 auch mit einer anderen Zahl ändern, aber je größer die Zahl, desto schlechter wird die "Zufälligkeit".
Keba
Aha. Danke für die Erklärung.
1

Rubin

Leider nur Mac. Wir soxziehen Bytes aus dem Mikrofon (als String, ahem ...), kehren sie um, um den Status-Header am Ende zu erhalten (* hust *), zerhacken ihn, hacken den Header ab und nehmen das MD5 der Chunks , lassen Sie die nicht numerischen Zeichen aus dem Hash fallen, addieren Sie die verbleibenden größeren ganzen Zahlen, kleben Sie eine 0.auf die Vorderseite, konvertieren Sie sie in einen Float, fertig.

Erzeugt Floats unterschiedlicher Länge im Intervall 0..1.

require 'open3'
require 'digest'

class InsecureRandom
  def self.random_number
    n = self.get_bytes
    .map! { |r| Digest::MD5.hexdigest(r) }
    .map! { |r| r.gsub(/[a-z]/, '') }
    .map!(&:to_i)
    .reduce(0,:+)

    "0.#{n}".to_f
  end

  private
  def self.get_bytes
    Open3.popen3('sox -d -q -e unsigned-integer -p') do |_, stdout, _|
      stdout.read(20000).reverse.split('\\').to_a.take(20)
    end
  end
end

randomish = Array.new(20) { InsecureRandom.random_number }
puts randomish
# >> 0.2333530765409607
# >> 0.17754047429753905
# >> 0.936039801228352
# >> 0.2781141892158962
# >> 0.6243140263525706
# >> 0.1583419168189452
# >> 0.2173713056635174
# >> 0.930577106355
# >> 0.11215268787922089
# >> 0.13292311877287152
# >> 0.14791818448435443
# >> 0.4864648362730452
# >> 0.5133193113765809
# >> 0.3076637743531015
# >> 0.16060112015793476
# >> 0.7294970251624926
# >> 0.18945368886946876
# >> 0.9970215825154781
# >> 0.13775531752383308
# >> 0.5794383903900283
SLD
quelle
1

C.

Zufälliges Generieren mithilfe der Prozess-ID.

#include <unistd.h>
#include <stdio.h>

int     main(void)
{
    int out;
    out *= out *= out = getpid();
    printf("%d\n", out % 1024);
    return (0);
}

Beispielausgabe:

-767
0
769
-1008
337
-768
369
-752
-415
0
-863
784
-463
256
657
Mantale
quelle
1

ROTIEREN

Wenn dies , würde ich gewinnen!

byte a
?a@
Der Doktor
quelle
0

Python

Pythons Prägnanz überrascht immer wieder. Da die Verwendung des zufälligen Bildes von imgur anscheinend nicht gültig ist, habe ich eine große Quelle der Zufälligkeit verwendet: den Chat von stackoverflow!

   import urllib.request

def getrand():
    req = urllib.request.Request("http://chat.stackoverflow.com/")
    response = urllib.request.urlopen(req)
    the_page = str(response.read())

    x = 1
    for char in the_page:
        x = (3*x + ord(char) + 1)%2**32

    print(x)

5 Versuche:

3258789746
1899058937
3811869909
274739242
1292809118

Nicht wirklich zufällig, aber keines davon ist es.

qwr
quelle
Ich denke, Regel 2 erlaubt keine URLs wiewhatever.com/random
izabera
@izabera 2 der anderen Antworten verwendet es?
qwr
Nein, Sie verwenden explizit zufällig generierte Inhalte. Die anderen Antworten greifen einfach auf eine nicht zufällige Webseite zu, um einen Startwert zu erhalten und dann eine Zufallszahl zu drucken.
Izabera
@izabera Ich habe meine zufällige Quelle geändert. Was denkst du jetzt darüber?
qwr
Jetzt ist es in Ordnung: D
Izabera
0

Perl

Ich habe viele Antworten gesehen, die HTTP-Anfragen stellten, was mir verschwenderisch erscheint, da unter der Decke Zufallszahlen auf dem Draht herumgereicht werden. Also habe ich beschlossen, einen Code zu schreiben, um einen auf einer niedrigeren Ebene zu wischen:

use IO::Socket::INET;
print ((sockaddr_in(getsockname(IO::Socket::INET->new(
    PeerAddr => "google.com", PeerPort => 80, Proto => "tcp"
))))[0]);

Gibt theoretisch zufällige Ports im Bereich 0..65535 an. In der Praxis gibt es eine Reihe von Ports, die Sie nie sehen werden, sodass die Verteilung alles andere als perfekt ist. Aber es ist AFAICT die minimale Menge an Arbeit, die Sie tun können, um Entropie von einem Remote-Host zu erhalten, bei dem ein Port geöffnet ist.

PS - Fehlerbehandlung bleibt dem Leser als Übung überlassen ;-)

skibrianski
quelle
0

C.

// alternating two pure-RNG inspired by http://xkcd.com/221/
int getRandomNumber()
{
   static int dice_roll = 0;
   dice_roll++;
   if ((dice_roll % 2) == 1)
   {
      return 4;
   } 
   else
   {
      return 5;
   } 
}

int main(int argc, char **argv)
{
    printf("%d\n%d\n", getRandomNumber(), getRandomNumber())
    return 0;
}
VX
quelle