Improvise a Hardware Random-Number Generator

51

9

Your task is to improvise a hardware random-number generator with whatever hardware you have lieing around.

Challenge

Write a program with the following properties:

  1. It prints either 0 or 1 (and nothing else).
  2. The output depends on a physical process and not just the internal state of the computer.
  3. There is no relation between outputs of subsequent runs (one minute apart).
  4. The output is not predictable with any realistic effort.
  5. The probability of the output being 0 is between 0.2 and 0.8.
  6. It runs in less than a minute with a reasonably high probability.

You must explain why your program has these properties, if it is not obvious.

Clarifications and Restrictions

The following may seem like an awful lot of restrictions for a popularity contest, but ultimatively it’s all to ensure that the program remains within the spirit of the question, somewhat works and to avoid solutions which are popular due to being a total overkill but are ultimatively rather boring.

  • The system time does not count as a physical process.
  • You may use any consumer-grade hardware you like from 8-inch floopy-disk drives to a USB rocket launcher to headphones – unless it is intended for random-number generation. A piece of hardware is consumer-grade, if it is mass-produced and costs less than 1000 $/€/£, so you cannot use radio telescopes, the CERN, MRIs or your home-built particle detector.
  • You can only make the most basic assumptions on the state and alignment of the hardware such as being switched on (if it has a power switch) and being properly installed and functional. For example you can assume a CD drive to be generally capable of reading a disk and not to be jammed, but you cannot assume it to be open or closed or to contain a disk. In another example you cannot assume two pieces of hardware to be aligned to allow for a special interaction, but you can assume them to be in the same room.
  • You may leave the hardware in any state you like, unless you break it.
  • You can and must assume the hardware to be in a natural environment, but nothing more. For example you can assume that the hardware is not positioned in a in tank of liquid helium nor in an extremely sound- and lightproof room nor in space. However, you cannot assume any sound- and lightsources to be present except those that are only avoidable with radical efforts.
  • Your program must run on a standard desktop computer with a non-esoteric operating system of your choice. You may employ any software that is not specifically designed for random-number generation.
  • You cannot assume Internet access.
  • You can neither assume humans to be present nor absent, but you can assume that nobody intentionally interfers with your program, e.g., by manually stopping a fan or running a program that does nothing but switching off the microphone as often as possible.
  • You can only make the most basic assumptions about the software settings. For example, you can assume drivers to be installed and activated but you must be prepared for the sound to be muted.
  • You may leave the software settings in any state you like.

Bonus

A special bounty was awarded to a particularly short solution. This was rather by numbers of instructions and similar than by characters. The winners were (tied according to my criteria):

I could only award one answer and Tejas Kale’s answer won by lot.

Wrzlprmft

Posted 2014-09-21T15:54:27.610

Reputation: 2 772

2Is a gyroscope like those found in newer smartphones and laptops considered consumer hardware? – Nzall – 2014-09-22T10:04:18.250

@NateKerkhofs: Yes. – Wrzlprmft – 2014-09-22T10:39:18.917

Actually, could we get a definition of "consumer-grade hardware"? Is "anything you can buy at at your local computer store for less than 500 USD, or that you can get as part of a 1,000 USD machine" an acceptable definition? – Nzall – 2014-09-22T11:11:27.460

@NateKerkhofs: Done. – Wrzlprmft – 2014-09-22T11:29:55.583

"with whatever hardware you have lieing around." I actually have a radio tuned to static connected to my server at home to study generating random numbers with it... maybe that could enhance Ells answer... – PlasmaHH – 2014-09-22T14:06:16.013

No full-fledged answer, because I currently don't have access to the necessary hard- and software, but -in my experience- the readings of the accelerometer of a tablet or smartphone fluctuate (even when the device is not moved) and may contain enough noise for an RNG. – Sebastian Negraszus – 2014-09-22T19:30:47.907

1

@SebastianNegraszus: There is already an answer using that.

– Wrzlprmft – 2014-09-22T19:35:05.963

1

Let me insert a little trivia here, there is a real random number generator based on Quantum Mechanics running at the Australian National University. Take a look: http://qrng.anu.edu.au/index.php

– Alexandre Teles – 2014-09-23T21:15:50.663

Cosmic-ray detectors are pretty good at this. – Carl Witthoft – 2014-09-25T11:45:27.833

Answers

28

Shell

Reads a single sample from the microphone stream and prints its least-significant bit, which should be dominated by noise.

EDIT: Changed to unmute the microphone ... and everything else too!

# 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 ))

Ell

Posted 2014-09-21T15:54:27.610

Reputation: 7 317

What if I have the mic muted? Shouldn't this be perfect silence? – None – 2014-09-22T09:30:55.527

3@yeti: Well, sure. But we're allowed to assume that "the hardware is switched on and functional", which I think covers that. – Ell – 2014-09-22T09:42:52.660

3unmuting everything is quite a big (and annoying) side-effect to a "pseudo random" binary generator, to me ^^ – Olivier Dulac – 2014-09-22T17:40:49.113

1You could try to feed the speakers with some data using cat /dev/urandom > /dev/dsp, just in case the computer is in a sound-proof room/chamber/box/case/space. – Ismael Miguel – 2014-09-24T08:54:43.743

just what I wanted to do! – shortstheory – 2014-09-24T11:29:16.913

albeit I wanted the mic source from my arduino – shortstheory – 2014-09-24T11:30:04.287

@IsmaelMiguel Every ADC generates enough noise even without an actual signal. – CL. – 2014-09-27T09:39:29.967

I don't know till which point that assumption isn't against the rules. – Ismael Miguel – 2014-09-27T19:04:25.983

@IsmaelMiguel: »you can assume that the hardware is not positioned […] in an extremely sound[…]proof room […].« – Wrzlprmft – 2014-10-01T14:27:42.807

@Wrzlprmft "However, you cannot assume any sound- and lightsources to be present except those that are only avoidable with radical efforts." You forgot this part............. – Ismael Miguel – 2014-10-01T17:46:08.210

@IsmaelMiguel: No I did not, but where did anybody assume the presence of such soundsources? – Wrzlprmft – 2014-10-01T18:14:21.620

@Wrzlprmft I didn't, that's why I said to feed the speakers with some data. It will work, and it complies with this part of the 3rd rule: In another example you cannot assume two pieces of hardware to be aligned to allow for a special interaction, but you can assume them to be in the same room.. Feeding the speakers with some sound (making sure also that the volume is on max) will be more within the rules. Since they are in the same room, this is enough. Remember also that You can only make the most basic assumptions on the state and alignment of the hardware such as being switched on[...] – Ismael Miguel – 2014-10-02T09:14:39.503

26

Bash

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

Gathers entropy from the response time of a single ping to localhost.

Note that the response time appears exactly thrice in the output of 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

All other numbers and constant and – more importantly – independent from the response time.

sed 's/[^1-9]/+/g' converts every zero and non-digit into plus signs, and echo $[...0&1] prints the parity of the resulting sum.

Dennis

Posted 2014-09-21T15:54:27.610

Reputation: 196 637

1It always prints 1 for me: CYGWIN_NT-6.2-WOW64 work 1.7.28(0.271/5/3) 2014-02-09 21:06 i686 Cygwin - ping has neither -q or -c here. – rr- – 2014-09-22T13:01:11.443

I don't know much about Cygwin. Is it possible that you are using de Windows ping utility? – Dennis – 2014-09-22T13:15:15.860

2Using Windows ping confirmed. I'm surprised. – rr- – 2014-09-22T13:41:06.957

Windows ping would return Pinging 127.0.0.1 with 32 bytes of data: Reply from 127.0.0.1: bytes=32 time<1ms TTL=128 – James Snell – 2014-09-22T14:02:51.567

1@JamesSnell: That's the problem then. Windows ping doesn't have enough precision; it will always show a time of 1 ms... – Dennis – 2014-09-22T14:05:22.660

6Seems like this violates restriction #2: Pinging localhost depends entirely on the internal state of the computer. – tophyr – 2014-09-22T19:15:27.510

2Difficult to say. @Dennis: Do you know where the fluctuation comes from? – Wrzlprmft – 2014-09-22T19:29:04.410

1@Wrzlprmft: Quite frankly, no. A ping to localhost is handled by the loopback device (which is virtual), but it still has to be handled at least by the CPU, so it depends on a physical process. – Dennis – 2014-09-22T21:54:48.567

I think in terms of rule coherence it would be safer to have a board with two Ethernet ports and a non-shielded cable between them, so your output depends more on the state of the cable and interference than the internals of the machine. – iFreilicht – 2014-09-23T11:11:56.150

According to @tophyr, for i in {0..1000};do echo $[$(ping -qc1 127.1|sed 's/[^1-9]/+/g')0&1];done | sort | uniq -c could sometime present (on my host) 198 0 // 802 1 which violate rule #5. (too close to 0.2, sometime under.) – F. Hauri – 2014-09-25T21:31:32.810

@F.Hauri: That's strange. On my machine, the zeros are always between 40 % and 60 % (and usually quite close to 50 %). – Dennis – 2014-09-26T02:20:24.493

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 here.

Uses the HTML5 DeviceMotion API on supported devices (mostly mobile devices). It turns the resulting acceleration object into JSON, hashes it, and takes the remainder modulo 2.

Most of the code is the hash function (damn you JavaScript, and your total lack of a standard library). It could probably be shorter, but I'm a sucker for a good hash function.

James_pic

Posted 2014-09-21T15:54:27.610

Reputation: 3 988

40"Please shake the device to generate new password." – PTwr – 2014-09-23T08:53:27.433

21

Python + Webcam

Using code shamelessly stolen from here, takes a shapshot using your webcam, hashes the data, and prints the least significant bit.

#!/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

James_pic

Posted 2014-09-21T15:54:27.610

Reputation: 3 988

@d_r_w Source on that? It doesn't sound illegal :P – Navin – 2015-09-08T17:50:44.647

@drheart Considering you can throw them to the trash https://www3.epa.gov/radtown/americium-smoke-detectors.html, it doesnt sound very likely?

– jinawee – 2019-02-03T00:10:51.953

I like the idea, but it is dependent on a) having a light source and b) having some moving parts within the room of the camera. If one of the above is not present, the hash will always be the same. Both are assumptions listed in the question (more or less): "However, you cannot assume any sound- and lightsources to be present except those that are only avoidable with radical efforts" and "You can neither assume humans to be present nor absent". I agree the last one doesn't exclude moving objects literally, but having some moving parts in the room seems more excludable than humans. – 11684 – 2014-09-22T17:07:37.227

8There is no "least significant bit" in a good hash. Yeah I know what you meant – gnibbler – 2014-09-22T17:36:07.290

11@11684, there's probably enough thermal noise etc. in the camera to prevent identical results – gnibbler – 2014-09-22T17:37:07.900

2The light should fluctuate quite a bit (outside light going up/down, and of course any "blinkenlights" the computer probably emits) – Olivier Dulac – 2014-09-22T17:42:27.507

1@11684: That’s more or less what I had in mind when I wrote: “For example you can assume that the hardware is not positioned […] in an extremely […] lightproof room […]”. – Wrzlprmft – 2014-09-22T19:30:36.920

7This is loosely based on something a friend of mine did. He was interested in using radioactive decay to generate truly random numbers. He dismantled a webcam and a smoke alarm, put the isotope next to the CCD, and wrote some code to feed the locations of detected beta emissions into /dev/random. However, we found that even if we sealed off all the light from the outside, there was a measurable amount of background noise on the CCD, although the beta emissions were still detectable. – James_pic – 2014-09-22T19:33:58.377

3https://github.com/bitplane/schrodingers-rng – James_pic – 2014-09-22T19:36:21.687

1Minor correction: americium 241 is an alpha emitter. – James_pic – 2014-09-22T19:39:30.760

@James_pic Additional information: Doing this is illegal in many countries. – drheart – 2014-10-01T19:49:41.147

1@d_r_w Do you mean the smoke alarm thing, or the webcam random number generator. Also, which countries? – James_pic – 2014-10-02T07:57:01.083

1The smoke alarm thing. Unsheilding the radioactive material in a smoke alarm can technically constitute a felony in the United States, for example. – drheart – 2014-10-02T16:11:18.097

15

Perl

Checks your Harddrive's response time, by timing three operations:

  • Reading its own source
  • Deleting itself
  • Writing itself again

Finally, the time taken is packed as a float, and the 11th most significant bit is used (second most significant bit of the 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))

primo

Posted 2014-09-21T15:54:27.610

Reputation: 30 891

1A program that deletes and writes itself to the disk is something I could only imagine a perl or python programmer to do. Very cool idea! – iFreilicht – 2014-09-23T11:18:29.717

This looks something that wouldn't touch any hardware and be deterministic when run within a VM, which is a very common scenario. – Peteris – 2014-09-23T22:23:41.750

1You'd want a flush to disk to make it depend on the disk instead of the cache (which is machine state, rule #2) – MSalters – 2014-09-24T10:48:25.973

14

Bash

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

sensors prints the current system temperatures along with the fan speed.

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' converts every zero and non-digit into plus signs, and echo $[...0&1] prints the parity of the resulting sum.

Regex and parity calculation borrowed from dennis's answer.

Tejas Kale

Posted 2014-09-21T15:54:27.610

Reputation: 343

This answer has been awarded a special bounty for a particularly short solution (just in case, anybody wonders). It was tied with Franki’s answer by my criteria and won by lot.

– Wrzlprmft – 2014-10-01T14:15:44.840

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

Uses everything, just in case...

Depends on

  • sensor readings of most hardware sensors (about all somehow expose their values somewhere in /sys or /proc)
  • number, memory layout and runtimes of all processes on the system (which may be considered "state of the system" but usually themselves depend on the timings of the hardware)
  • depending on the system, various values in /proc/<pid>/s* (e.g. sched/schedstat) depend on the speed of the hardware necessary to bring those processes alive.
  • things I might not have thought of that are available in those files too.

Runtime on my system is ~10s, but may vary a lot. Especially don't run this as root, or at least modify it to exclude /proc/kcore (unless you are willing to spend a lot of time to include the entropy contained in there, which would probably really include everything)

PlasmaHH

Posted 2014-09-21T15:54:27.610

Reputation: 1 084

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

Puts the wi-fi card into monitor mode, dumps 30 seconds worth of packets received (including unreadable encrypted data from neighbouring networks), takes the sha512 hash of the packet data, and returns 1 if the first letter of the hash is 0-7. Assumes that your wi-fi card is wlan0, and that you do not currently have a mon0 device.

If there are no nearby wi-fi devices, then the output will be predictable, as it will be the same every time.

James_pic

Posted 2014-09-21T15:54:27.610

Reputation: 3 988

1Hmm, I would not count the absence of wi-fi devices so unnatural that you can neglect it. – Wrzlprmft – 2014-09-22T19:37:37.597

3@Wrzlprmft It depends where you are. It is unnatural to not have wifi networks in a crowded urban area. On a universal scale, not being in a near total vacuum is not a fair assumption, nor if limited to Earth is it fair to assume the computer is not submerged in water. – Ian D. Scott – 2014-09-23T00:10:28.823

1@IanD.Scott: Well, the next wifi-free area for me is actually in the cellar (don’t ask me why I know this). And I am not living in the middle of nowhere. Anyway, the number of computers in wifi-free suroundings certainly exceeds the number of (working) computers in water or a vacuum by several orders of magnitude. (It all comes down to your definition of natural in the end, I guess.) – Wrzlprmft – 2014-09-23T08:10:26.303

8

Modern 8086 compatible processors manufactured by Intel contain an easily accessible peripheral that generates proper randomness. Driving that peripheral is done using the rdrand instruction which either generates a random bit pattern or sets the carry flag if the peripheral is unavailable or out of entropy.

The following short program for 80386 Linux checks if the peripheral is available by means of the cpuid instruction and tries to generate a random number. If either the peripheral or a random number is not available, the program will terminate with a status of 1. If a random number could be generated, either a 1 or a 0 is printed out and the program terminates with exit status 0.

Save as rand.s and assemble with

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

Here is the entire assembly:

        .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

And a dump of the resulting 77 bytes of machine code:

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

FUZxxl

Posted 2014-09-21T15:54:27.610

Reputation: 9 656

12“You may use any […] hardware […] – unless it is intended for random-number generation.” – The goal is to improvise a hardware random-number generator, not to use one. – Wrzlprmft – 2014-09-22T13:23:34.240

18@Wrzlprmft rdrand is not a random number generator. It's a peripheral made for the NSA to mess with people's cryptography. – FUZxxl – 2014-09-22T13:29:49.623

1Actually, I didn't notice that sentence before writing this program. My bad. – FUZxxl – 2014-09-22T13:30:15.190

7

bash

Aiming for the most unnecessarily expensive random number gathering method. Time how long it takes to spawn emacs a million times, then use Dennis' trick to turn the time taken into a single Boolean (takes about 7 seconds on my machine).

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

Chris Jefferson

Posted 2014-09-21T15:54:27.610

Reputation: 435

1with averaging, the deviation can be very small… – Display Name – 2014-09-23T08:13:25.633

7

Arduino Mega1280

edit: updated version that is robust against having anything plugged into the pins. The idea relies on the fact that the ATMega1280 uses a separate internal oscillator for the watchdog oscillator. I simply setup a watchdog interrupt which sets a flag, have a counter based on the system clock (on the Arduino this is a 16MHz external crystal), and allow clock jitter/variance do the work.

#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;
}

helloworld922

Posted 2014-09-21T15:54:27.610

Reputation: 2 503

5

Javascript

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

Takes video input.

You can see the screenshot that it used to calculate the random number.

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;

soktinpk

Posted 2014-09-21T15:54:27.610

Reputation: 4 080

1I just found a bug in FF, "Stop sharing" doesn't turn of the webcam! – Frank – 2014-09-28T08:01:12.330

3

Shell on Linux

Measure read speed of a hard drive + access time of a frequently updated directory on this disc which layout is unpredictable.

# 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))

requires:

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.

This approach has the advantage of not modifying any data on the system and not requiring perl over primo's one.

Franki

Posted 2014-09-21T15:54:27.610

Reputation: 81

3

Shell

Tested on Linux, but maybe your U*IX does have /proc/stat as well?

This starts only a single additional process, reads only a single additional file (not even on disc) and is 37 characters short. It's also pretty fast.

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

One may think that this is determined by all kernel and userland process states, but that is not the case, since /proc/stat also includes IO-wait time, time to sevice hardware interrupts, time spent in idle task and some other which all depend on external hardware input.

Franki

Posted 2014-09-21T15:54:27.610

Reputation: 81

This answer was tied for the bounty for a particularly short answer by my criteria and lost by lot. – Wrzlprmft – 2014-10-01T14:20:33.493

2

Matlab

The microphone solution:

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

Records 10 seconds of sound, finds the number of negative samples in the recording and outputs 0 if this number is even and 1 if it's odd. Thus 0 with 50% probability. The approach means that even small amounts of noice, unavoidable in a silent recording, will be enough to generate a random output. The following slightly longer code speeds up the number generator by using a shorter recording, compensated with a higher bitrate, which gives more noise.

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

In a test under quiet conditions, I find that in 100 runs of the latter code, the code outputs zero 51 times. 100 runs under noisy conditions produced zero 40 times.

Edit: Thanks to Emil for pointing out a flaw in the original code :-)

Abulafia

Posted 2014-09-21T15:54:27.610

Reputation: 141

1What happens if the record is not silent and there are no non-zero samples? – Emil – 2014-09-25T20:55:16.040

1Good question. Some zeros tend to pop up anyway, because the values oscillate around zero (sound vibrations) and there's a limited number of decimals. But now that you mention it, it should of course be "<0" rather than ~=0, so that I count the number of negative samples instead. :-] This too is random. – Abulafia – 2014-09-26T08:37:03.693

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.

Uses the 3DS's motion sensor. The Z axis of the accelerometer is usually around -1 (because of gravity), and due to random noise, it can sometimes be above or below that.

Here's one that uses the microphone:

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

12Me21

Posted 2014-09-21T15:54:27.610

Reputation: 6 110

0

Bash

(Thanks, Dennis.)

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

Soham Chowdhury

Posted 2014-09-21T15:54:27.610

Reputation: 1 449

1If I am not fully mistaken, this only relies only on the system time and the current software state of the computer and moreover requires a user to be logged in. – Wrzlprmft – 2014-09-22T19:41:38.730

@Wrzlprmft: w shows a list of logged in users, which can be empty. The system load is based on the CPU queue length. – Dennis – 2014-09-22T22:36:17.313

Well, I could replace w with top. – Soham Chowdhury – 2014-09-23T07:19:12.017

0

Takes the least significant bit of the computer's accelerometer (needs the hdaps Linux module):

#!/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)

This basically measures the noise of the sensor.

Petr Pudlák

Posted 2014-09-21T15:54:27.610

Reputation: 4 272

-3

Bash

I took Soham’s own suggestion (using top):

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

Edit: It works the same way Soham's does. It turns all non numeric characters in the output of top into '+' and then evaulates the parity of the resulting string.

the 'b' flag to top runs it in batch mode so that it reports all processes, not just the first screenful and 'n1' says to just run 1 iteration of top.

Keith Wolters

Posted 2014-09-21T15:54:27.610

Reputation: 99

Is there really any difference between your and Soham's program? – clismique – 2017-05-31T12:27:25.127