Random number generator (device)

From Rosetta Code
Jump to: navigation, search
Task
Random number generator (device)
You are encouraged to solve this task according to the task description, using any language you may know.

If your system has a means to generate random numbers involving not only a software algorithm (like the /dev/urandom devices in Unix), show how to obtain a random 32-bit number from that mechanism.

Contents

[edit] Ada

random.adb:

with Ada.Streams.Stream_IO;
with Ada.Text_IO;
procedure Random is
Number : Integer;
Random_File : Ada.Streams.Stream_IO.File_Type;
begin
Ada.Streams.Stream_IO.Open (File => Random_File,
Mode => Ada.Streams.Stream_IO.In_File,
Name => "/dev/random");
Integer'Read (Ada.Streams.Stream_IO.Stream (Random_File), Number);
Ada.Streams.Stream_IO.Close (Random_File);
Ada.Text_IO.Put_Line ("Number:" & Integer'Image (Number));
end Random;

[edit] BBC BASIC

Requires Windows XP or later.

      SYS "SystemFunction036", ^random%, 4
PRINT ~random%

[edit] C

It works on systems having /dev/urandom, like GNU/Linux.

#include <stdio.h>
#include <stdlib.h>
 
#define RANDOM_PATH "/dev/urandom"
 
int main(void)
{
unsigned char buf[4];
unsigned long v;
FILE *fin;
 
if ((fin = fopen(RANDOM_PATH, "r")) == NULL) {
fprintf(stderr, "%s: unable to open file\n", RANDOM_PATH);
return EXIT_FAILURE;
}
if (fread(buf, 1, sizeof buf, fin) != sizeof buf) {
fprintf(stderr, "%s: not enough bytes (expected %u)\n",
RANDOM_PATH, (unsigned) sizeof buf);
return EXIT_FAILURE;
}
fclose(fin);
v = buf[0] | buf[1] << 8UL | buf[2] << 16UL | buf[3] << 24UL;
printf("%lu\n", v);
return 0;
}

[edit]
Library: BSD libc

arc4random() appeared in OpenBSD 2.1 and has spread to many BSD systems. This function runs an ARC4 random number generator that takes entropy from a kernel device. (This kernel device is sysctl kern.arandom in OpenBSD, or /dev/urandom in some other systems.)

#include <inttypes.h> /* PRIu32 */
#include <stdlib.h> /* arc4random */
#include <stdio.h> /* printf */
 
int
main()
{
printf("%" PRIu32 "\n", arc4random());
return 0;
}

[edit]
Library: OpenSSL

OpenSSL can generate random numbers. The default generator uses SHA1. For Unix systems, OpenSSL will gather entropy by reading a kernel device like /dev/urandom, or by using EGD, the Entropy Gathering Daemon. For other systems, OpenSSL might use a different source of entropy.

#include <inttypes.h>
#include <stdio.h>
 
#include <openssl/err.h>
#include <openssl/rand.h>
 
int
main()
{
uint32_t v;
 
if (RAND_bytes((unsigned char *)&v, sizeof v) == 0) {
ERR_print_errors_fp(stderr);
return 1;
}
printf("%" PRIu32 "\n", v);
return 0;
}

[edit] Windows

Works with: MinGW
#include <stdio.h>  /* printf */
#include <windows.h>
#include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
 
int
main()
{
HCRYPTPROV p;
ULONG i;
 
if (CryptAcquireContext(&p, NULL, NULL,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) {
fputs("CryptAcquireContext failed.\n", stderr);
return 1;
}
if (CryptGenRandom(p, sizeof i, (BYTE *)&i) == FALSE) {
fputs("CryptGenRandom failed.\n", stderr);
return 1;
}
printf("%lu\n", i);
CryptReleaseContext(p, 0);
return 0;
}

[edit] C++

std::random_device is a uniformly-distributed integer random number generator that produces non-deterministic random numbers.

Note that std::random_device may be implemented in terms of a pseudo-random number engine if a non-deterministic source (e.g. a hardware device) is not available to the implementation.

See the C++ section on Random number generator (included) for the list of pseudo-random number engines available.

Works with: C++11
#include <iostream>
#include <string>
#include <random>
 
int main()
{
std::random_device rd;
std::uniform_int_distribution<int> dist;
 
std::cout << "Random Number: " << dist(rd) << std::endl;
}

[edit] C#

using System;
using System.Security.Cryptography;
 
private static int GetRandomInt()
{
int result = 0;
var rng = new RNGCryptoServiceProvider();
var buffer = new byte[4];
 
rng.GetBytes(buffer);
result = BitConverter.ToInt32(buffer, 0);
 
return result;
}

[edit] Forth

variable rnd
 
: randoms ( n -- )
s" /dev/random" r/o open-file throw
swap 0 do
dup rnd 1 cells rot read-file throw drop
rnd @ .
loop
close-file throw ;

[edit] Go

In the Go library is crypto/rand, a source specified to use dev/urandom on Unix-like systems and the CryptGenRandom API on Windows. Also implemented here is a source using dev/random, if you really want it. On my system it would print a few numbers then hang until I moved the mouse or pressed some keys on the keyboard.

package main
 
import (
"crypto/rand"
"encoding/binary"
"fmt"
"io"
"os"
)
 
func main() {
testRandom("crypto/rand", rand.Reader)
testRandom("dev/random", newDevRandom())
}
 
func newDevRandom() (f *os.File) {
var err error
if f, err = os.Open("/dev/random"); err != nil {
panic(err)
}
return
}
 
func testRandom(label string, src io.Reader) {
fmt.Printf("%s:\n", label)
var r int32
for i := 0; i < 10; i++ {
if err := binary.Read(src, binary.LittleEndian, &r); err != nil {
panic(err)
}
fmt.Print(r, " ")
}
fmt.Println()
}

[edit] Groovy

Based, necessarily, on Java solution:

def rng = new java.security.SecureRandom()

Test:

(0..4).each { println rng.nextInt() }

Output:

380425053
-1003791794
-1972330603
1152610574
714616658

[edit] Icon and Unicon

The following is Unicon-specific but trivially converted into Icon.

procedure main(A)
n := integer(A[1])|5
every !n do write(rand(4))
end
 
procedure rand(n)
f := open("/dev/urandom") | stop("Cannot get to urandom!")
x := 0
every !n do x := x*256 + ord(reads(f,1))
close(f)
return x
end

Sample runs:

->urand
910795827
1135996175
3545606085
944909079
2464790129
->

[edit] J

Untested:

256#.a.i.1!:11'/dev/urandom';0 4

Fallback:

256#.a.i.4{.host'dd if=/dev/urandom bs=4 count=1'

Note: this assumes that J is running on linux.

[edit] Java

import java.security.SecureRandom;
 
public class RandomExample {
public static void main(String[] args) {
SecureRandom rng = new SecureRandom();
 
/* Prints a random signed 32-bit integer. */
System.out.println(rng.nextInt());
}
}

[edit] Haskell

Works with: GHC version 7.4.1
#!/usr/bin/runhaskell
 
import System.Entropy
import Data.Binary.Get
import qualified Data.ByteString.Lazy as B
 
main = do
bytes <- getEntropy 4
print (runGet getWord32be $ B.fromChunks [bytes])

[edit] Lasso

file(`/dev/urandom`)->readSomeBytes(4)->export32bits
Output:
723217350

[edit] Mathematica

rand32[] := RandomInteger[{-2^31, 2^31 - 1}]

Example: create array of 10 rand32 numbers

Table[rand32[], {i, 1, 10}]

Output:

{355587317, -869860319, -91421859, 1605907693, 101463390, 891823090, 
-531713717, -1038608428, 1717313407, 674189312}

[edit] NetRexx

Works with: Mac OS X
and probably other UNIX systems that provide /dev/random or /dev/urandom random data source devices.
/* NetRexx */
options replace format comments java crossref savelog symbols binary
 
import java.math.BigInteger
 
randomDevNameFile = File
randomDevNameList = ['/dev/random', '/dev/urandom'] -- list of random data source devices
randomDevIStream = InputStream
do
loop dn = 0 to randomDevNameList.length - 1
randomDevNameFile = File(randomDevNameList[dn])
if randomDevNameFile.exists() then leave dn -- We're done! Use this device
randomDevNameFile = null -- ensure we don't use a non-existant device
end dn
if randomDevNameFile == null then signal FileNotFoundException('Cannot locate a random data source device on this system')
 
-- read 8 bytes from the random data source device, convert it into a BigInteger then display the result
randomBytes = byte[8]
randomDevIStream = BufferedInputStream(FileInputStream(randomDevNameFile))
randomDevIStream.read(randomBytes, 0, randomBytes.length)
randomDevIStream.close()
randomNum = BigInteger(randomBytes)
say Rexx(randomNum.longValue()).right(24) '0x'Rexx(Long.toHexString(randomNum.longValue())).right(16, 0)
catch ex = IOException
ex.printStackTrace()
end
return
 
/*
To run the program in a loop 10 times from a bash shell prompt use:
for ((i=0; i<10; ++i)); do java <program_name>; done # Shell loop to run the command 10 times
*/

 

Output:

$ for ((i=0; i<10; ++i)); do java RRandomGen; done # Shell loop to run the command 10 times
    -3724652236619320966 0xcc4f60865c70f17a
    -8287324416757903696 0x8cfd8259e0b94eb0
    -2951181559250748016 0xd70b4c02052cfd90
     8171526404483923658 0x716717f863fd3eca
    -4285529734202916706 0xc486bd699676009e
     4783094698411310978 0x4260f74949dc3f82
     6972277496665184225 0x60c28171482d97e1
    -2382194670272317046 0xdef0be919c96f98a
     7952058769071853043 0x6e5b6351938ecdf3
    -1857830580859698636 0xe637a8ee0f000234
$

[edit] Nimrod

var f = open("/dev/urandom")
var r: int32
discard f.readBuffer(addr r, 4)
close(f)
echo r

[edit] OCaml

OCaml's default integers are 31 bits on 32 bits architectures:

let input_rand_int ic =
let i1 = int_of_char (input_char ic)
and i2 = int_of_char (input_char ic)
and i3 = int_of_char (input_char ic)
and i4 = int_of_char (input_char ic) in
i1 lor (i2 lsl 8) lor (i3 lsl 16) lor (i4 lsl 24)
 
let () =
let ic = open_in "/dev/urandom" in
let ri31 = input_rand_int ic in
close_in ic;
Printf.printf "%d\n" ri31;
;;

but if we really want 32 bits integers there is a module for this:

let input_rand_int32 ic =
let i1 = Int32.of_int (int_of_char (input_char ic))
and i2 = Int32.of_int (int_of_char (input_char ic))
and i3 = Int32.of_int (int_of_char (input_char ic))
and i4 = Int32.of_int (int_of_char (input_char ic)) in
let i2 = Int32.shift_left i2 8
and i3 = Int32.shift_left i3 16
and i4 = Int32.shift_left i4 24 in
Int32.logor i1 (Int32.logor i2 (Int32.logor i3 i4))
 
let () =
let ic = open_in "/dev/urandom" in
let ri32 = input_rand_int32 ic in
close_in ic;
Printf.printf "%ld\n" ri32;
;;

[edit] Pascal

This works with FreePascal on "unixoids":

program RandomNumberDevice;
var
byteFile: file of byte;
randomByte: byte;
begin
assign(byteFile, '/dev/urandom');
reset (byteFile);
read (byteFile, randomByte);
close (byteFile);
writeln('The random byte is: ', randomByte);
end.
 

Output:

>: ./RandomNumberDevice
The random byte is: 9
>: ./RandomNumberDevice
The random byte is: 237

[edit] Perl

Typically one would use a module as they will work on UNIX, Win32, and other O/S's. Crypt::Random::Seed, for instance, will use Win32 sources, EGD/PRNGD, /dev/u?random, or if none of those exist for some reason, a userspace entropy method.

use Crypt::Random::Seed;
my $source = Crypt::Random::Seed->new( NonBlocking => 1 ); # Allow non-blocking sources like /dev/urandom
print "$_\n" for $source->random_values(10); # A method returning an array of 32-bit values

or (similar but many more dependencies):

use Crypt::Random::Source qw/get_weak/;    # Alternately get_strong
print unpack('L*',get_weak(4)), "\n" for 1..10;

Or we can read values from /dev/urandom ourselves:

sub read_random {
my $device = '/dev/urandom';
open my $in, "<:raw", $device # :raw because it's not unicode string
or die "Can't open $device: $!";
 
sysread $in, my $rand, 4 * shift;
unpack('L*', $rand);
}
 
print "$_\n" for read_random(10);

Whether /dev/urandom is good enough for cryptographic work is debated, though on most UNIX systems it is at least as good as the Win32 Crypto API.

[edit] Perl 6

A lazy list of random numbers:

my $UR = open("/dev/urandom", :bin) or die "Can't open /dev/urandom: $!";
my @random-spigot := gather loop { take $UR.read(1024).unpack("L*") }
 
.say for @random-spigot[^10];
Output:
1431009271
1702240522
670020272
588612037
1864913839
2155430433
1690056587
385405103
2366495746
692037942

[edit] PicoLisp

: (in "/dev/urandom" (rd 4))
-> 2917110327

[edit] ProDOS

Uses math module:

printline -random- 

[edit] PureBasic

PureBasic has the source for the random data is the "/dev/urandom" device on Linux or Mac OSX and the "Microsoft Cryptography API" on Windows.

If OpenCryptRandom()
MyRandom = CryptRandom(#MAXLONG)
CloseCryptRandom()
EndIf

[edit] Python

import random
rand = random.SystemRandom()
rand.randint(1,10)

[edit] Racket

 
#lang racket
;; Assuming a device to provide random bits:
(call-with-input-file* "/dev/random"
(λ(i) (integer-bytes->integer (read-bytes 4 i) #f)))
 

[edit] REXX

/*REXX program generates a random  32-bit  number using the  RANDOM bif.*/
/*───────── The 32-bit random number is unsigned and constructed from */
/*───────── two smaller 16-bit numbers, and it's expressed in decimal.*/
/*───────── Note: the REXX random bif has a maximum range of 100,000.*/
 
numeric digits 10 /*ensure REXX has enough room. */
_=2**16 /*a handy-dandy constant to have.*/
 
say random(0,_-1)*_+random(0,_-1) /*gen an unsigned 32-bit random #*/

output

4294967296

[edit] Ruby

Ruby 1.8.7 introduces the 'securerandom' library. For MRI users, this library tries to get random numbers by loading OpenSSL, or opening /dev/urandom, or calling CryptGenRandom.

Works with: Ruby version 1.8.7
require 'securerandom'
SecureRandom.random_number(1 << 32)

[edit] Tcl

package require Tcl 8.5
 
# Allow override of device name
proc systemRandomInteger {{device "/dev/random"}} {
set f [open $device "rb"]
binary scan [read $f 4] "I" x
close $f
return $x
}

Usage:

% puts [systemRandomInteger]
636131349

[edit] UNIX Shell

od -An -N 4 -t u4 /dev/urandom

[edit] XPL0

The random number generator is seeded with the 32-bit system timer each time a program starts. From then on, a linear congruential algorithm is used (that passes the Diehard test suite). Since the Ran intrinsic routine returns a signed positive integer (modulo the argument), the value is limited to 31 bits.

code Ran=1;
int R;
R:= Ran($7FFF_FFFF)
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox