Improvvisa un generatore di numeri casuali hardware


53

Il tuo compito è improvvisare un generatore di numeri casuali hardware con qualsiasi hardware tu abbia in giro.

Sfida

Scrivi un programma con le seguenti proprietà:

  1. Stampa o 0o 1(e nient'altro).
  2. L'output dipende da un processo fisico e non solo dallo stato interno del computer.
  3. Non esiste alcuna relazione tra le uscite delle corse successive (a un minuto di distanza).
  4. L'output non è prevedibile con alcuno sforzo realistico.
  5. La probabilità che l'output sia 0compreso tra 0,2 e 0,8.
  6. Funziona in meno di un minuto con una probabilità ragionevolmente alta.

Devi spiegare perché il tuo programma ha queste proprietà, se non è ovvio.

Chiarimenti e restrizioni

Quanto segue può sembrare un sacco di restrizioni per un concorso di popolarità, ma alla fine è tutto per garantire che il programma rimanga nello spirito della domanda, funzioni in qualche modo ed evitare soluzioni che sono popolari a causa dell'eccessivo totale ma sono in definitiva piuttosto noioso.

  • Il tempo di sistema non conta come processo fisico.
  • Puoi usare qualsiasi hardware di livello consumer che ti piaccia dalle unità floppy-disk da 8 pollici a un lanciarazzi USB alle cuffie, a meno che non sia destinato alla generazione di numeri casuali. Un componente hardware è di qualità consumer, se prodotto in serie e costa meno di 1000 $ / € / £, quindi non è possibile utilizzare radiotelescopi, CERN, MRI o il rilevatore di particelle di casa.
  • È possibile fare solo le ipotesi di base sullo stato e sull'allineamento dell'hardware, ad esempio l'accensione (se dispone di un interruttore di alimentazione) e l'installazione e il funzionamento adeguati. Ad esempio, si può presumere che un'unità CD sia generalmente in grado di leggere un disco e di non essere inceppata, ma non si può presumere che sia aperta o chiusa o che contenga un disco. In un altro esempio non puoi presumere che due componenti hardware siano allineati per consentire un'interazione speciale, ma puoi supporre che siano nella stessa stanza.
  • È possibile lasciare l'hardware in qualsiasi stato, a meno che non lo si rompa.
  • Puoi e devi presumere che l'hardware si trovi in ​​un ambiente naturale, ma niente di più. Ad esempio, si può presumere che l'hardware non sia posizionato in un serbatoio di elio liquido né in una stanza estremamente insonorizzata e leggera né nello spazio. Tuttavia, non puoi presumere che siano presenti suoni e fonti di luce tranne quelli evitabili solo con sforzi radicali.
  • Il programma deve essere eseguito su un computer desktop standard con un sistema operativo non esoterico di tua scelta. È possibile utilizzare qualsiasi software non specificamente progettato per la generazione di numeri casuali.
  • Non puoi assumere l'accesso a Internet.
  • Non puoi presumere che gli umani siano presenti o assenti, ma puoi presumere che nessuno interferisca intenzionalmente con il tuo programma, ad esempio fermando manualmente un ventilatore o eseguendo un programma che non fa altro che spegnere il microfono il più spesso possibile.
  • È possibile fare solo le ipotesi di base sulle impostazioni del software. Ad esempio, si può presumere che i driver siano installati e attivati, ma è necessario essere pronti per l'audio da silenziare.
  • È possibile lasciare le impostazioni del software in qualsiasi stato desiderato.

indennità

Un premio speciale è stato assegnato a una soluzione particolarmente breve. Questo era piuttosto per numero di istruzioni e simile che per caratteri. I vincitori erano (legati secondo i miei criteri):

Ho potuto assegnare solo una risposta e la risposta di Tejas Kale ha vinto a sorte.


2
Un giroscopio come quelli che si trovano nei nuovi smartphone e laptop è considerato hardware di consumo?
Nzall,

@NateKerkhofs: Sì.
Wrzlprmft,

In realtà, potremmo ottenere una definizione di "hardware di consumo"? "Qualcosa che puoi acquistare nel tuo negozio di computer locale per meno di 500 USD o che puoi ottenere come parte di una macchina da 1.000 USD" è una definizione accettabile?
Nzall,


1
Vorrei inserire un po 'di curiosità qui, c'è un vero generatore di numeri casuali basato sulla Meccanica Quantistica in esecuzione presso la Australian National University. Dai un'occhiata: qrng.anu.edu.au/index.php
Alexandre Teles,

Risposte:


28

Conchiglia

Legge un singolo campione dal flusso del microfono e stampa il suo bit meno significativo, che dovrebbe essere dominato dal rumore.

EDIT: modificato per riattivare il microfono ... e tutto il resto!

# Warning - unmutes EVERYTHING!
for DEV in `amixer | grep Simple | sed -e "s/.*'\(.*\)'.*/\\1/" -e "s/ /~/g"`
do
    amixer -q -- sset "`echo $DEV | sed 's/~/ /g'`" unmute 100% 2>/dev/null
done

echo $(( `od -N1 -d < /dev/dsp | head -n1 | sed 's/.* //'` & 1 ))

Cosa succede se ho il microfono disattivato? Non dovrebbe essere questo il silenzio perfetto?
yeti,

3
@yeti: Beh, certo. Ma possiamo ammettere che "l'hardware è acceso e funzionale", che a mio avviso copre.
Ell,

3
riattivare tutto è piuttosto un grande (e fastidioso) effetto collaterale per un generatore binario "pseudo casuale", per me ^^
Olivier Dulac,

1
È possibile provare ad alimentare alcuni altoparlanti con alcuni dati utilizzando cat /dev/urandom > /dev/dsp, nel caso in cui il computer si trovi in ​​una stanza / camera / scatola / scatola / spazio insonorizzate.
Ismael Miguel,

proprio quello che volevo fare!
cortometraggio,

26

bash

echo $[`ping -qc1 127.1|sed 's/[^1-9]/+/g'`0&1]

Raccoglie entropia dal tempo di risposta di un singolo ping a localhost.

Si noti che il tempo di risposta appare esattamente tre volte nell'output di ping -qc1:

PING 127.1 (127.0.0.1) 56(84) bytes of data.

--- 127.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.044/0.044/0.044/0.000 ms

Tutti gli altri numeri e costanti e - soprattutto - indipendenti dal tempo di risposta.

sed 's/[^1-9]/+/g'converte ogni zero e non cifra in segni più e echo $[...0&1]stampa la parità della somma risultante.


1
Esso stampa sempre 1 per me: CYGWIN_NT-6.2-WOW64 work 1.7.28(0.271/5/3) 2014-02-09 21:06 i686 Cygwin- pingnon ha né -qo -cqui.
r-

2
Utilizzo di Windows pingconfermato. Sono sorpreso.
r-

1
@JamesSnell: Questo è il problema allora. Il ping di Windows non ha abbastanza precisione; mostrerà sempre un tempo di 1 ms ...
Dennis

6
Sembra che ciò violi la restrizione n. 2: il ping localhost dipende interamente dallo stato interno del computer.
tophyr

2
Difficile da dire @Dennis: sai da dove viene la fluttuazione?
Wrzlprmft,

25

JavaScript + HTML5 DeviceMotion

var hash = function(x) {
    var h = 0
    for (var i = 0; i < x.length; i++) {
        h += x.charCodeAt(i)
        h ^= h << 5
        h ^= h >> 3
        h ^= h << 13
        h &= 0xffff
    }
    return h
}
var listener = function(e) {
    var accelerationString = JSON.stringify(e.acceleration)
    var hashed = hash(accelerationString)
    alert(hashed % 2)
    window.removeEventListener("devicemotion", listener, true)
}
window.addEventListener("devicemotion", listener, true);

JSFiddle qui .

Utilizza l'API HTMLM DeviceMotion su dispositivi supportati (principalmente dispositivi mobili). Trasforma l' accelerationoggetto risultante in JSON, l'hash e prende il resto modulo 2.

La maggior parte del codice è la funzione hash (maledetto JavaScript e la tua totale mancanza di una libreria standard). Probabilmente potrebbe essere più breve, ma sono un fanatico di una buona funzione hash.


40
"Scuoti il ​​dispositivo per generare una nuova password."
PTwr,

21

Python + Webcam

Usando il codice spudoratamente rubato da qui , scatta una foto usando la tua webcam, esegue l'hashing dei dati e stampa il bit meno significativo.

#!/usr/bin/python
import pygame.camera, hashlib

pygame.camera.init()
cam = pygame.camera.Camera(pygame.camera.list_cameras()[0])
cam.start()
raw = cam.get_raw()
cam.stop()
pygame.camera.quit()

h = hashlib.sha256()
h.update(raw)
print ord(h.digest()[-1]) % 2

8
Non esiste un "bit meno significativo" in un buon hash. Sì, lo so cosa volevi dire
Gnibbler,

11
@ 11684, probabilmente c'è abbastanza rumore termico ecc. Nella fotocamera per evitare risultati identici
gnibbler

2
La luce dovrebbe fluttuare un po '(la luce esterna va su / giù, e ovviamente ogni "luce lampeggiante" che il computer probabilmente emette)
Olivier Dulac,

7
Questo è vagamente basato su qualcosa che ha fatto un mio amico. Era interessato all'utilizzo del decadimento radioattivo per generare numeri veramente casuali. Ha smontato una webcam e un rilevatore di fumo, ha messo l'isotopo vicino al CCD e ha scritto un codice per alimentare le posizioni delle emissioni beta rilevate in / dev / random. Tuttavia, abbiamo scoperto che anche se avessimo sigillato tutta la luce dall'esterno, sul CCD c'era una quantità misurabile di rumore di fondo, sebbene le emissioni beta fossero ancora rilevabili.
James_pic,


15

Perl

Controlla i tempi di risposta del tuo Harddrive, programmando tre operazioni:

  • Leggendo la propria fonte
  • Eliminare se stesso
  • Scrivere di nuovo se stesso

Infine, il tempo impiegato viene impacchettato come un galleggiante e viene utilizzato l'undicesimo bit più significativo (il secondo bit più significativo della mantissa).

use Time::HiRes qw(time);

$t1 = time;
open SELF, "<$0";
read SELF, $_, $^H;
close SELF;

unlink $0;

open SELF, ">$0";
print SELF $_;
close SELF;

print 1&unpack(xB3, pack(f, time-$t1))

1
Un programma che si cancella e si scrive sul disco è qualcosa che potrei solo immaginare un programmatore perl o python da fare. Un'idea davvero fantastica!
iFreilicht,

Questo sembra qualcosa che non toccherebbe alcun hardware ed essere deterministico quando eseguito all'interno di una VM, che è uno scenario molto comune.
Peteris,

1
Vorresti un flush su disco per farlo dipendere dal disco invece che dalla cache (che è lo stato del computer, regola n. 2)
MSalters

14

bash

echo $[`sensors|sed 's/[^1-9]/+/g'`0&1]

sensors stampa le temperature correnti del sistema insieme alla velocità della ventola.

acpitz-virtual-0
Adapter: Virtual device
temp1:        +52.0°C  (crit = +98.0°C)

thinkpad-isa-0000
Adapter: ISA adapter
fan1:        3510 RPM

coretemp-isa-0000
Adapter: ISA adapter
Physical id 0:  +54.0°C  (high = +86.0°C, crit = +100.0°C)
Core 0:         +51.0°C  (high = +86.0°C, crit = +100.0°C)
Core 1:         +46.0°C  (high = +86.0°C, crit = +100.0°C)

sed 's/[^1-9]/+/g'converte ogni zero e non cifra in segni più e l'eco $[...0&1]stampa la parità della somma risultante.

Calcolo del regex e della parità preso in prestito dalla risposta di Dennis.


A questa risposta è stata assegnata una ricompensa speciale per una soluzione particolarmente breve (per ogni evenienza, qualcuno si chiede). Era legato alla risposta di Franki dai miei criteri e vinto a sorte.
Wrzlprmft,

12

bash

(echo -en "ibase=16;";(find /proc/[0-9]*/s* -type f -maxdepth 2 ; find /sys /proc/[^0-9]* -type f) 2>&1 | xargs -n1 sha256sum  2>&1 | sha256sum | tr abcdef ABCDEF | sed 's/  -/%2/' )| bc

Usa tutto, per ogni evenienza ...

Dipende da

  • letture dei sensori della maggior parte dei sensori hardware (circa tutti in qualche modo espongono i loro valori da qualche parte in /syso /proc)
  • numero, layout di memoria e runtime di tutti i processi sul sistema (che possono essere considerati "stato del sistema" ma di solito dipendono dai tempi dell'hardware)
  • a seconda del sistema, vari valori in /proc/<pid>/s*(es. sched / schedstat) dipendono dalla velocità dell'hardware necessario per rendere vivi questi processi.
  • cose che potrei non aver pensato che sono disponibili anche in quei file.

Il tempo di esecuzione sul mio sistema è di ~ 10 secondi, ma può variare molto. Soprattutto non eseguirlo come root, o almeno modificarlo per escluderlo /proc/kcore(a meno che tu non sia disposto a spendere molto tempo per includere l'entropia in esso contenuta, che probabilmente includerebbe davvero tutto)


9

Shell + Wi-Fi

sudo airmon-ng start wlan0 > /dev/null && sudo dumpcap -a duration:30 -i mon0 -w out.cap > /dev/null && sha512sum out.cap | grep -c "^[0-7]" && sudo airmon-ng stop mon0 > /dev/null

Mette la scheda Wi-Fi in modalità monitor, scarica i pacchetti ricevuti per 30 secondi (compresi i dati crittografati illeggibili dalle reti vicine), accetta l'hash sha512 dei dati dei pacchetti e restituisce 1 se la prima lettera dell'hash è 0-7 . Suppone che sia la tua scheda Wi-Fi wlan0e che al momento non disponi dimon0 dispositivo.

Se non ci sono dispositivi Wi-Fi nelle vicinanze, l'output sarà prevedibile, poiché sarà sempre lo stesso.


1
Hmm, non considererei l'assenza di dispositivi Wi-Fi così innaturali che puoi trascurarlo.
Wrzlprmft,

3
@Wrzlprmft Dipende da dove ti trovi. È innaturale non avere reti wifi in un'area urbana affollata. Su una scala universale, non essere in un vuoto quasi totale non è un presupposto equo, né se limitato alla Terra è giusto presumere che il computer non sia immerso nell'acqua.
Ian D. Scott,

1
@ IanD.Scott: Beh, la prossima area senza wifi per me è in realtà in cantina (non chiedermi perché lo so). E non vivo in mezzo al nulla. Ad ogni modo, il numero di computer in ambienti senza wifi supera certamente il numero di computer (funzionanti) nell'acqua o nel vuoto di diversi ordini di grandezza. (Tutto
dipende

8

I moderni processori compatibili 8086 prodotti da Intel contengono una periferica facilmente accessibile che genera una casualità adeguata. La guida di quella periferica viene eseguita utilizzando l' rdrandistruzione che genera uno schema di bit casuale o imposta il flag di trasporto se la periferica non è disponibile o è fuori dall'entropia.

Il seguente breve programma per 80386 Linux verifica se la periferica è disponibile tramite l' cpuidistruzione e cerca di generare un numero casuale. Se la periferica o un numero casuale non sono disponibili, il programma verrà chiuso con uno stato di 1. Se un numero casuale potrebbe essere generato, sia una 1o 0viene stampato e termina programma con stato di uscita 0.

Salva come rand.se assembla con

as --32 -o rand.o rand.s
ld -melf_i386 -o rand rand.o

Ecco l'intero assemblaggio:

        .globl _start
        .type _start,@function
_start:
        # check if the cpuid instruction is available by trying to
        # toggle the id flag in the eflags register
        pushfl
        mov (%esp),%eax
        btc $21,%eax    # toggle id bit
        push %eax
        popfl           # check if id bit was saved
        pushfl
        pop %eax        # load new flags
        pop %ecx        # load original flags
        xor %ecx,%eax   # difference is in %eax
        bt $21,%eax     # check if bit was flipped
        jnc .Lfailure

        # if we reach this part, we have a cpuid instruction
        # next, check if rdrand exists
        mov $1,%eax     # load cpuid leaf 1
        cpuid
        bt $30,%ecx     # is rdrnd available?
        jnc .Lfailure

        # let's try to get some random data
        rdrand %ax      # don't waste randomness; one bit would suffice
        jnc .Lfailure   # no randomness available
        and $1,%eax     # isolate one bit of randomness
        add $0x30,%al   # 0x30 = '0'
        push %eax
        mov $4,%eax     # prepare a write system call
        mov $1,%ebx
        mov %esp,%ecx   # where we placed the data before
        mov %ebx,%edx   # one byte
        int $0x80

        # okay, we're done here. Let's exit
        mov %ebx,%eax   # do an exit system call with status 0
        xor %ebx,%ebx
        int $0x80

.Lfailure:
        mov $1,%eax     # do an exit system call with status 1
        mov %eax,%ebx
        int $0x80

        .size _start,.-_start

E un dump dei risultanti 77 byte di codice macchina:

08048098 <_start>:
 8048098:   9c                      pushf  
 8048099:   8b 04 24                mov    (%esp),%eax
 804809c:   0f ba f8 15             btc    $0x15,%eax
 80480a0:   50                      push   %eax
 80480a1:   9d                      popf   
 80480a2:   9c                      pushf  
 80480a3:   58                      pop    %eax
 80480a4:   59                      pop    %ecx
 80480a5:   31 c8                   xor    %ecx,%eax
 80480a7:   0f ba e0 15             bt     $0x15,%eax
 80480ab:   73 2f                   jae    80480dc <_start+0x44>
 80480ad:   b8 01 00 00 00          mov    $0x1,%eax
 80480b2:   0f a2                   cpuid  
 80480b4:   0f ba e1 1e             bt     $0x1e,%ecx
 80480b8:   73 22                   jae    80480dc <_start+0x44>
 80480ba:   66 0f c7 f0             rdrand %ax
 80480be:   73 1c                   jae    80480dc <_start+0x44>
 80480c0:   83 e0 01                and    $0x1,%eax
 80480c3:   04 30                   add    $0x30,%al
 80480c5:   50                      push   %eax
 80480c6:   b8 04 00 00 00          mov    $0x4,%eax
 80480cb:   bb 01 00 00 00          mov    $0x1,%ebx
 80480d0:   89 e1                   mov    %esp,%ecx
 80480d2:   89 da                   mov    %ebx,%edx
 80480d4:   cd 80                   int    $0x80
 80480d6:   89 d8                   mov    %ebx,%eax
 80480d8:   31 db                   xor    %ebx,%ebx
 80480da:   cd 80                   int    $0x80
 80480dc:   b8 01 00 00 00          mov    $0x1,%eax
 80480e1:   89 c3                   mov    %eax,%ebx
 80480e3:   cd 80                   int    $0x80

12
"È possibile utilizzare qualsiasi [...] hardware [...] - a meno che non sia destinato alla generazione di numeri casuali ." - L'obiettivo è improvvisare un generatore di numeri casuali hardware, non usarne uno.
Wrzlprmft,

18
@Wrzlprmft rdrandnon è un generatore di numeri casuali. È una periferia creata per la NSA per pasticciare con la crittografia delle persone.
FUZxxl,

1
In realtà, non ho notato quella frase prima di scrivere questo programma. Colpa mia.
FUZxxl,

7

bash

Puntando al metodo di raccolta di numeri casuali più inutilmente costoso. Tempo quanto tempo ci vuole per generare emacs un milione di volte, quindi usa il trucco di Dennis per trasformare il tempo impiegato in un singolo booleano (impiega circa 7 secondi sulla mia macchina).

$[`(time (seq 1000000 | xargs -P1000 emacs  >/dev/null 2>&1)) |& sed 's/[^1-9]/+/g'`0&1]

1
con la media, la deviazione può essere molto piccola ...
Sarge Borsch,

7

Arduino Mega1280

modifica: versione aggiornata che è robusta per non avere nulla collegato ai pin. L'idea si basa sul fatto che ATMega1280 utilizza un oscillatore interno separato per l'oscillatore del watchdog. Ho semplicemente impostato un interrupt watchdog che imposta un flag, ho un contatore basato sull'orologio di sistema (su Arduino si tratta di un cristallo esterno a 16 MHz) e consento al jitter / varianza del clock di fare il lavoro.

#include <avr/interrupt.h>

int time;
volatile bool wdt_ran;

// watchdog interrupt handler
ISR(WDT_vect, ISR_BLOCK)
{
  wdt_ran = true;
}

void setup()  
{
  // setup watchdog interrupt
  cli();
  MCUSR &= ~(1 << WDRF);
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDIE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
  sei();
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
}

void loop()
{
  if(wdt_ran)
  {
    Serial.println(abs(time%2));
    wdt_ran = false;
  }
  ++time;
}

5

Javascript

http://jsfiddle.net/prankol57/9a6s0gmv/

Accetta l'ingresso video.

Puoi vedere lo screenshot che ha usato per calcolare il numero casuale.

var m = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

var constraints = {
  video: {
    mandatory: {
      maxWidth: 350,
      maxHeight: 350
    }
  },
  audio: false
};

var video = document.querySelector("video"), canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = 350;
canvas.height = 350;

function start() {
    m.call(navigator, constraints, function (stream) {
        video.src = window.URL.createObjectURL(stream);
    }, function() {
        alert("An error occured. Did you deny permission?");
    });
}

if (m) {
    start();
} else {
    alert('getUserMedia() is not supported in your browser');
}

function getRandomData() {
    var ctx = canvas.getContext("2d");
    ctx.drawImage(video, 0, 0);
    var data = ctx.getImageData(0, 0, 350, 350).data;
    var total = 0;
    for (var i = 0; i < data.length; ++i) {
        total += data[i];
        total %= 2;
    }
    alert("The random number is " + total);
}

document.querySelector("button").onclick = getRandomData;

1
Ho appena trovato un bug in FF, "Stop sharing" non gira la webcam!
Frank,

3

Shell su Linux

Misura la velocità di lettura di un disco rigido + il tempo di accesso di una directory aggiornata di frequente su questo disco il cui layout è imprevedibile.

# Set this to the device node of whatever drive you want to measure
DRIVE_DEVICE=sda
# This must be a path that is
# a) on device "/dev/$DRIVE_PATH"
# b) frequently updated to add additional access time randomization due to
#    less-predictable disk layout due to less-predictable time, amount and
#    ordering uf updates, like logfile directories, maybe cache directories.
FIND_PATH=/var/log
# Better than using 'sync' - sync only the disk that we actually read from
# also sync both internal drive and system buffers
hdparm -f -F "/dev/$DRIVE_DEVICE"
# Note: bash's built-in time command doesn't support formats :/
# Note: the result is only going to be as good as the system's time command,
#       which isn't necessarily equally good on other U*ICes
t=$(command time -f '%e' -- find "$FIND_PATH" -printf '' 2>&1)
echo $((${t#*.}&1))

richiede:

1) read and execute access to every directory under "$FIND_PATH"
2) sending (flush) control commands to a hard drive via a device node.
   Requires root access per default, but can be delegated to a less privileged user
   either by using sudo on this script or by applying
       chgrp 'some_system_group' "$DRIVE_DEVICE" &&
       chmod g+rx "$DRIVE_DEVICE"
   if this is acceptable on your system.

Questo approccio ha il vantaggio di non modificare alcun dato sul sistema e di non richiedere perl a quello di primo.


3

Conchiglia

Testato su Linux, ma forse il tuo U * IX ha anche / proc / stat?

Questo avvia solo un singolo processo aggiuntivo, legge solo un singolo file aggiuntivo (nemmeno su disco) ed è corto di 37 caratteri. È anche abbastanza veloce.

t=1`sum /proc/stat`;echo $[${t% *}&1]

Si potrebbe pensare che ciò sia determinato da tutti gli stati del kernel e degli stati utente, ma non è così, dal momento che / proc / stat include anche il tempo di attesa IO, il tempo di settare gli interrupt di processo, il tempo trascorso in task inattivo e altri che tutti dipende dall'input hardware esterno.


Questa risposta era legata alla generosità di una risposta particolarmente breve dai miei criteri e persa a sorte.
Wrzlprmft,

2

Matlab

La soluzione per microfono:

recObj=audiorecorder;recordblocking(recObj,10);rem(sum(getaudiodata(recObj)<0),2)

Registra 10 secondi di suono, trova il numero di campioni negativi nella registrazione ed emette 0 se questo numero è pari e 1 se è dispari. Quindi 0 con probabilità del 50%. L'approccio significa che anche piccole quantità di rumore, inevitabili in una registrazione silenziosa, saranno sufficienti per generare un output casuale. Il seguente codice leggermente più lungo accelera il generatore di numeri usando una registrazione più breve, compensata con un bitrate più alto, che dà più rumore.

recObj=audiorecorder(8000,16,1);recordblocking(recObj,0.1);rem(sum(getaudiodata(recObj)<0),2)

In un test in condizioni silenziose, trovo che in 100 esecuzioni di quest'ultimo codice, il codice emetta zero 51 volte. 100 corse in condizioni rumorose prodotte zero 40 volte.

Modifica: grazie a Emil per aver segnalato un difetto nel codice originale :-)


1
Cosa succede se il record non è silenzioso e non ci sono campioni diversi da zero?
Emil,

1
Buona domanda. Alcuni zeri tendono ad apparire comunque, perché i valori oscillano attorno allo zero (vibrazioni del suono) e c'è un numero limitato di decimali. Ma ora che lo dici, ovviamente dovrebbe essere "<0" anziché ~ = 0, quindi conto invece il numero di campioni negativi. : -] Anche questo è casuale.
Abulafia,

0

bash

(Grazie, Dennis.)

echo $[`w|sed 's/[^1-9]/+/g'`0&1]

1
Se non mi sbaglio completamente, questo si basa solo sull'ora di sistema e sullo stato attuale del software del computer e inoltre richiede che un utente abbia effettuato l'accesso.
Wrzlprmft

@Wrzlprmft: wmostra un elenco di utenti che hanno effettuato l'accesso, che può essere vuoto. Il carico del sistema si basa sulla lunghezza della coda della CPU.
Dennis,

Bene, potrei sostituirlo wcon top.
Soham Chowdhury,

0

Prende il bit meno significativo dell'accelerometro del computer (richiede il hdapsmodulo Linux):

#!/usr/bin/env python
import re
m = re.search('([-\d]+),([-\d]+)',
              open('/sys/devices/platform/hdaps/position', 'r').read())
print((int(m.group(1)) ^ int(m.group(2))) & 1)

Questo fondamentalmente misura il rumore del sensore.


0

SmileBASIC

XON MOTION 'enable motion sensor
ACCEL OUT ,,Z 'get Z acceleration (up/down)
PRINT Z<-1 'if Z is less than -1, output 1, otherwise 0.

Utilizza il sensore di movimento del 3DS. L'asse Z dell'accelerometro è generalmente intorno a -1 (a causa della gravità) e, a causa del rumore casuale, a volte può essere al di sopra o al di sotto di quello.

Eccone uno che utilizza il microfono:

XON MIC 'enable microphone
DIM REC%[0] 'make array
MICSTART 0,3,1 'start recording. 0=8180Hz, 3=8 bit unsigned, 1=1 second
WAIT 1 'delay (1 frame is enough since we only check the first sample)
MICSAVE MIC 'save recording
PRINT MIC[0]>0 'if the first sample isn't negative, output 1

-3

bash

Ho preso il suggerimento di Soham (usando top):

echo $[`top -bn1|sed 's/[^1-9]/+/g'`0&1]

Modifica: funziona allo stesso modo di Soham. Trasforma tutti i caratteri non numerici nell'output di top in '+' e quindi eva la parità della stringa risultante.

il flag 'b' in alto lo esegue in modalità batch in modo che riporti tutti i processi, non solo il primo schermo e 'n1' dice di eseguire solo 1 iterazione di top.


C'è davvero qualche differenza tra il tuo programma e quello di Soham?
clismique,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.