# Random without Time-Basis [closed]

Computers do not out-of-nowhere create random numbers without basis, as most likely, time is the universal basis of randomness.

I want you to create a code that creates random numbers with these rules:

• Time is not allowed to be the basis, at any point of the program.
• Predefined random/pseudo-random functions are not allowed.
• Numbers generated can be within any range. Well at least two different integers :D
• Numbers are echoed.
• It is unclear what you mean by "Numbers generated can be within any range". Do you mean the coder is free to choose a range? Or that they must support any range the user requests? Both of these are problematic. If the user requests a range, what if they request numbers outside the bounds of the built in data types? And if the coder is free to choose, I choose integers between 1 and 1. :D Commented Mar 2, 2014 at 14:25
• Should have been a code-golf... Commented Mar 2, 2014 at 15:30
• I started this question as popularity-question, would code-golf a better fit for this? Commented Mar 3, 2014 at 1:19
• @Daniel Yeah but let this question be popularity-question and post a new question with code golf with new rules(on random generation) that'll be fun Commented Mar 3, 2014 at 2:37
• using the internet as a seed seems like cheating doesn't it? Commented Mar 6, 2014 at 2:22

# JavaScript

That was fun!

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.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())


I wrote up the Mersenne Twister in JS. Then, I realized I had to get a seed from somewhere.

So, I decided I would get it from the Stack Exchange API! (I could use localStorage and increment a counter, but that's no fun.) So, I grabbed the 10 most recently active answers, and then I just took every 4 or less consecutive digits in the response and added them up.

These seeds are always different, since Stack Overflow is constantly updating (and my quota keeps going down!) The numbers include answer IDs, question IDs, scores, up/downvote counts, owner rep/IDs, and the wrapper data (quota and such). On one run I got 256845, then 270495, and then 256048, etc....

This logs 10 random 32-bit two's-complement numbers to the console. Sample output:

247701962
-601555287
1363363842
-1184801866
1761791937
-163544156
2021774189
2140443959
1764173996
-1176627822


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

}


The magic is in the public NoTimeRandom(). Arrays cast to strings can confuse new programmers, as the numbers are random. Sample (for char[]: [C@4a8e91eb). The next method is copied from java.util.Random.

Sample output:

134277366
467041052
-555611140
-1741034686
1420784423


Let's test the effectiveness of this rng:

In my answer to Approximate a Bell Curve, the data generation I used depends on a good rng. Let's run it with this as the rng. Output:

Just as I thought. This is a pretty lousy rng.

# C

#include <stdio.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;
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++)
{
}

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

done = 0;
}


I'm not sure if this qualifies or not based on the "time is not allowed" standard, because it is basically using the scheduler as the source of entropy by intentionally ignoring thread safety. It works by using a fairly basic psuedo-random function (Lehmer random number generator) with a hard coded initial seed. It then starts 20 threads that all run the Lehmer calculation with a shared set of variables.

Seems to work fairly well, here are a couple of consecutive runs:

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: Gave this a little more thought and realized that this isn't time based at all. Even with a completely deterministic scheduler, the entropy isn't coming from the time slices - it is coming from the loading of all the running processes on the system.

EDIT 2 After taking some inspiration from @Quincunx posting a bell curve, I dumped 12MB of randomness into a file and uploaded it to CAcert. It failed all of the diehard tests, but clocked a respectable 7.999573 out of 8 on the ENT test (only Potentially deterministic). Curiously, doubling the thread count made it worse.

# C

It generates a random number in the 0-255 range by taking the seed from https://stackoverflow.com/questions using 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);
}


Sample run:

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


# C++

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


### output

any 5 random numbers

three samples

• 1st, 2nd and 5th are pretty close, same pattern repeated in all 3 examples. not exactly the expected output from a random number generator. Commented Mar 3, 2014 at 2:41
• @izabera When it comes to pointers in generating random numbers...everything depends on your computer(the RAM and processor) maybe the address fed by 'new int' into 'ptr' is being currently used! You tried to running this code ? Commented Mar 3, 2014 at 2:49
• Let me add a little change Commented Mar 3, 2014 at 2:53
• i tried it now, on my machine it seems like i always get things like 11230576, 0, 11206992, 0, 2053725299, which still doesn't seem random to me. Commented Mar 3, 2014 at 3:00
• check it out at ideone Commented Mar 3, 2014 at 3:04

# perl

What's all this rubbish with getting seeds over the internet? Sounds like cheating to me ;-) I prefer to give my seed to a cryptographic hash function instead, and give output in the range 0 to 2^160-1 like so:

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'  Anytime you have entropy of uncertain quality, a way to distribute it more regularly (but not increase its quality!) is to pipe it into the likes of SHA1 or MD5 or so, as I've done here. For pre-hash seeds, I've used pid and the address of a random reference. You could of course add other inputs for more entropy, eg on x86 you can use TSC - (but inlining assembly code in perl is a bit of a bear, so I skipped it). If you want to have different output than the guy on the next computer over, simply adjust "some_salt" to be a string of your liking. Or leave it out altogether if you are a minimalist =) • I'd guess that any cryptographic function worth its name in a standard library uses a cryptographically secure RNG internally. Commented Mar 8, 2014 at 14:22 • I'm not sure about that. Digest::MD5 / Digest::SHA1 produce completely deterministic, repeatable output, so what does it need a random number for? Commented Mar 8, 2014 at 14:25 • Sorry! I just flew over your answer and thought that you were generating a key instead of a digest. Commented Mar 8, 2014 at 14:40 # Java My solution abuses hashCode() method of Object class. 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()); } } }  Sample output: 31859448 22101035 11593610 4580332 25736626 32157998 3804398 32440180 19905449 2772678  Motivated by other answer's demonstrating the randomness of the solution, I changed my solution to return the middle 16 bits of the int returned by 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(); } }  I generated a 19 MB file (consisting of 107 short) and submit it to CACert. Here is the screenshot of the result (it has been edited to look nice, but the numbers are left as it is): I was surprised at the result, since it clocks 7.999991 at Entropy test and passes (?) all 7 Diehard tests. Javascript Generating random with user mouse move 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)};  Last five copied data: 9637090187003 7828470680762 6045869361238 4220720695015 2422653391073 Bash, range: ints between 0 and 1 echo -n & echo "$! % 2" | bc

• So you mean it picks 0 or 1 only?
– user10766
Commented Mar 4, 2014 at 0:38
• Yep. Should fulfill "Numbers generated can be within any range. Well at least two different integers :D", shouldn‘t it?
– Keba
Commented Mar 4, 2014 at 0:40
• I guess so. Do you think you could expand it to a bigger range?
– user10766
Commented Mar 4, 2014 at 0:44
• Just echo -n & echo \$! will do, but be a very bad RNG. You can also change 2 with any other number, but the bigger the number, the worse gets the "randomness".
– Keba
Commented Mar 4, 2014 at 7:52
• I see. Thanks for the explanation.
– user10766
Commented Mar 4, 2014 at 16:17

Ruby

Unfortunately Mac only. We use sox to pull bytes from the microphone (as a string, ahem...), reverse it to get the status header on the end (*cough*), chop it up, chop off the header, take the MD5 of the chunks, ditch the non-numeric chars from the hash, add the remaining largish integers together, stick a 0. on the front, convert to a float, done.

Generates floats of varying length on the interval 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, _|
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


C

Generating random using process ID.

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

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


Sample output :

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


# SPIN

If this was , i would win!

byte a
?a@


# python

Python's conciseness never ceases to amaze. Since using imgur's random image is not valid apparently, I've used a great source of randomness: stackoverflow's chat!

   import urllib.request

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

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

print(x)


5 trials:

3258789746
1899058937
3811869909
274739242
1292809118


Not truly random but then again none of these are.

• i think rule 2 doesn't allow urls like whatever.com/random Commented Mar 3, 2014 at 3:09
• @izabera 2 of the other answers used it?
– qwr
Commented Mar 3, 2014 at 3:11
• nope, you're explicitly using randomly generated content. the other answers just access to some non-random webpage to get a seed and then print a random number. Commented Mar 3, 2014 at 3:30
• @izabera I've changed my random source. What do you think of it now?
– qwr
Commented Mar 3, 2014 at 6:28
• now it's fine :D Commented Mar 3, 2014 at 6:33

# perl

I saw a lot of answers which made HTTP requests, which seems wasteful to me because under the covers there are random numbers being passed about on the wire. So I decided to write some code to swipe one at a lower level:

use IO::Socket::INET;
))))[0]);


Gives random ports in the range 0..65535, theoretically. In practice, there are a number of ports you will never see, so the distribution is far from perfect. But it is, AFAICT the minimal amount of work you can do to get some entropy from a remote host that has a port open.

PS - Error handling is left as an exercise to the reader ;-)

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