Random number generator (device)

From Rosetta Code
Revision as of 17:52, 14 March 2020 by Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Task
Random number generator (device)
You are encouraged to solve this task according to the task description, using any language you may know.
Task

If your system has a means to generate random numbers involving not only a software algorithm   (like the /dev/urandom devices in Unix),   then:

show how to obtain a random 32-bit number from that mechanism.

AArch64 Assembly

Linux provides getrandom syscall for most architectures, which draws random bytes from /dev/urandom by default.

The syscall number on AArch64 is 278.

<lang ARM_Assembly>.equ STDOUT, 1 .equ SVC_WRITE, 64 .equ SVC_GETRANDOM, 278 .equ SVC_EXIT, 93

.text .global _start

_start: stp x29, x30, [sp, -32]! // allocate buffer space at [sp] mov x29, sp mov x0, sp mov x1, #4 bl _getrandom // getrandom(&tmp, 4); ldr w0, [sp] bl print_uint64 // print_uint64(tmp); ldp x29, x30, [sp], 32 mov x0, #0 b _exit // exit(0);

// void print_uint64(uint64_t x) - print an unsigned integer in base 10. print_uint64: // x0 = remaining number to convert // x1 = pointer to most significant digit // x2 = 10 // x3 = x0 / 10 // x4 = x0 % 10 // compute x0 divmod 10, store a digit, repeat if x0 > 0 ldr x1, =strbuf_end mov x2, #10 1: udiv x3, x0, x2 msub x4, x3, x2, x0 add x4, x4, #48 mov x0, x3 strb w4, [x1, #-1]! cbnz x0, 1b // compute the number of digits to print, then call write() ldr x3, =strbuf_end_newline sub x2, x3, x1 mov x0, #STDOUT b _write

.data strbuf: .space 31 strbuf_end: .ascii "\n" strbuf_end_newline: .align 4

.text //////////////// system call wrappers // ssize_t _write(int fd, void *buf, size_t count) _write: mov x8, #SVC_WRITE svc #0 ret

// ssize_t getrandom(void *buf, size_t buflen, unsigned int flags=0) _getrandom: mov x2, #0 mov x8, #SVC_GETRANDOM svc #0 ret

// void _exit(int retval) _exit: mov x8, #SVC_EXIT svc #0</lang>

Ada

random.adb: <lang Ada>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;</lang>

ARM Assembly

Works with: as version Raspberry Pi

<lang ARM Assembly>

/* ARM assembly Raspberry PI */ /* program urandom.s */

/* Constantes */ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ READ, 3 .equ WRITE, 4 .equ OPEN, 5 .equ CLOSE, 6

.equ O_RDONLY, 0 @ open for reading only

.equ BUFFERSIZE, 4 @ random number 32 bits

/* Initialized data */ .data szFileName: .asciz "/dev/urandom" @ see linux doc szCarriageReturn: .asciz "\n" /* datas error display */ szMessErreur: .asciz "Error detected.\n" szMessErr: .ascii "Error code hexa : " sHexa: .space 9,' '

                    .ascii "  decimal :  "

sDeci: .space 15,' '

                    .asciz "\n"

/* datas message display */ szMessResult: .ascii "Random number :" sValue: .space 12,' '

                    .asciz "\n"

/* UnInitialized data */ .bss sBuffer: .skip BUFFERSIZE @ buffer result

/* code section */ .text .global main main:

   ldr r0,iAdrszFileName               @ File name
   mov r1,#O_RDONLY                    @  flags
   mov r2,#0                           @ mode
   mov r7,#OPEN                        @ open file
   svc #0 
   cmp r0,#0                           @ error ?
   ble error
   mov r8,r0                           @ save FD
   mov r4,#0                           @ loop counter

1:

   mov r0,r8                           @ File Descriptor
   ldr r1,iAdrsBuffer                  @ buffer address
   mov r2,#BUFFERSIZE                  @ buffer size
   mov r7,#READ                        @ call system read file
   svc 0 
   cmp r0,#0                           @ read error ?
   ble error
   ldr r1,iAdrsBuffer                  @ buffer address
   ldr r0,[r1]                         @ display buffer value
   ldr r1,iAdrsValue
   bl conversion10
   ldr r0,iAdrszMessResult
   bl affichageMess
   add r4,#1                           @ increment counter
   cmp r4,#10                          @ maxi ?
   blt 1b                              @ no -> loop


end:

   mov r0,r8
   mov r7, #CLOSE                      @ call system close file
   svc #0 
   cmp r0,#0
   blt error
   mov r0,#0                           @ return code
   b 100f

error:

   ldr r1,iAdrszMessErreur             @ error message
   bl   displayError
   mov r0,#1                           @ return error code

100: @ standard end of the program

   mov r7, #EXIT                       @ request to exit program
   svc 0                               @ perform system call

iAdrsBuffer: .int sBuffer iAdrsValue: .int sValue iAdrszMessResult: .int szMessResult iAdrszFileName: .int szFileName iAdrszMessErreur: .int szMessErreur iAdrszCarriageReturn: .int szCarriageReturn

/******************************************************************/ /* display text with size calculation */ /******************************************************************/ /* r0 contains the address of the message */ affichageMess:

   push {r0,r1,r2,r7,lr}                       @ save  registers 
   mov r2,#0                                   @ counter length */

1: @ loop length calculation

   ldrb r1,[r0,r2]                             @ read octet start position + index 
   cmp r1,#0                                   @ if 0 its over
   addne r2,r2,#1                              @ else add 1 in the length
   bne 1b                                      @ and loop 
                                               @ so here r2 contains the length of the message 
   mov r1,r0                                   @ address message in r1 
   mov r0,#STDOUT                              @ code to write to the standard output Linux
   mov r7, #WRITE                              @ code call system "write" 
   svc #0                                      @ call system
   pop {r0,r1,r2,r7,lr}                        @ restaur registers
   bx lr                                       @ return

/***************************************************/ /* display error message */ /***************************************************/ /* r0 contains error code r1 : message address */ displayError:

   push {r0-r2,lr}                         @ save registers
   mov r2,r0                               @ save error code
   mov r0,r1
   bl affichageMess
   mov r0,r2                               @ error code
   ldr r1,iAdrsHexa
   bl conversion16                         @ conversion hexa
   mov r0,r2                               @ error code
   ldr r1,iAdrsDeci                        @ result address
   bl conversion10S                        @ conversion decimale
   ldr r0,iAdrszMessErr                    @ display error message
   bl affichageMess

100:

   pop {r0-r2,lr}                          @ restaur registers
   bx lr                                   @ return 

iAdrszMessErr: .int szMessErr iAdrsHexa: .int sHexa iAdrsDeci: .int sDeci /******************************************************************/ /* Converting a register to hexadecimal */ /******************************************************************/ /* r0 contains value and r1 address area */ conversion16:

   push {r1-r4,lr}                          @ save registers
   mov r2,#28                               @ start bit position
   mov r4,#0xF0000000                       @ mask
   mov r3,r0                                @ save entry value

1: @ start loop

   and r0,r3,r4                             @ value register and mask
   lsr r0,r2                                @ move right 
   cmp r0,#10                               @ compare value
   addlt r0,#48                             @ <10  ->digit
   addge r0,#55                             @ >10  ->letter A-F
   strb r0,[r1],#1                          @ store digit on area and + 1 in area address
   lsr r4,#4                                @ shift mask 4 positions
   subs r2,#4                               @ counter bits - 4 <= zero  ?
   bge 1b                                   @ no -> loop

100:

   pop {r1-r4,lr}                                     @ restaur registers 
   bx lr     

/***************************************************/ /* Converting a register to a signed decimal */ /***************************************************/ /* r0 contains value and r1 area address */ conversion10S:

   push {r0-r4,lr}       @ save registers
   mov r2,r1             @ debut zone stockage
   mov r3,#'+'           @ par defaut le signe est +
   cmp r0,#0             @ negative number ? 
   movlt r3,#'-'         @ yes
   mvnlt r0,r0           @ number inversion
   addlt r0,#1
   mov r4,#10            @ length area

1: @ start loop

   bl divisionpar10U
   add r1,#48            @ digit
   strb r1,[r2,r4]       @ store digit on area
   sub r4,r4,#1          @ previous position
   cmp r0,#0             @ stop if quotient = 0
   bne 1b	
   strb r3,[r2,r4]       @ store signe 
   subs r4,r4,#1         @ previous position
   blt  100f             @ if r4 < 0 -> end
   mov r1,#' '           @ space

2:

   strb r1,[r2,r4]       @store byte space
   subs r4,r4,#1         @ previous position
   bge 2b                @ loop if r4 > 0

100:

   pop {r0-r4,lr}        @ restaur registers
   bx lr  

/***************************************************/ /* division par 10 unsigned */ /***************************************************/ /* r0 dividende */ /* r0 quotient */ /* r1 remainder */ divisionpar10U:

   push {r2,r3,r4, lr}
   mov r4,r0                                          @ save value
   //mov r3,#0xCCCD                                   @ r3 <- magic_number lower  raspberry 3
   //movt r3,#0xCCCC                                  @ r3 <- magic_number higter raspberry 3
   ldr r3,iMagicNumber                                @ r3 <- magic_number    raspberry 1 2
   umull r1, r2, r3, r0                               @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0) 
   mov r0, r2, LSR #3                                 @ r2 <- r2 >> shift 3
   add r2,r0,r0, lsl #2                               @ r2 <- r0 * 5 
   sub r1,r4,r2, lsl #1                               @ r1 <- r4 - (r2 * 2)  = r4 - (r0 * 10)
   pop {r2,r3,r4,lr}
   bx lr                                              @ leave function 

iMagicNumber: .int 0xCCCCCCCD

</lang>

Batch File

The dynamic environmental variable %random% contains a number between 0 and 32767. <lang dos> @echo %random% </lang>

BBC BASIC

Requires Windows XP or later. <lang bbcbasic> SYS "SystemFunction036", ^random%, 4

     PRINT ~random%</lang>

C

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

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  1. 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;

}</lang>

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

<lang c>#include <inttypes.h> /* PRIu32 */

  1. include <stdlib.h> /* arc4random */
  2. include <stdio.h> /* printf */

int main() {

 printf("%" PRIu32 "\n", arc4random());
 return 0;

}</lang>

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.

<lang c>#include <inttypes.h>

  1. include <stdio.h>
  1. include <openssl/err.h>
  2. 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;

}</lang>

Windows

Works with: MinGW

<lang c>#include <stdio.h> /* printf */

  1. include <windows.h>
  2. 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;

}</lang>

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

<lang cpp>#include <iostream>

  1. include <random>

int main() {

   std::random_device rd;
   std::uniform_int_distribution<long> dist; // long is guaranteed to be 32 bits
   
   std::cout << "Random Number: " << dist(rd) << std::endl;

}</lang>

C#

<lang csharp>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;

}</lang>

Park-Miller random number generator <lang csharp> const long m = 2147483647L; const long a = 48271L; const long q = 44488L; const long r = 3399L; static long r_seed = 12345678L;

public static byte gen() {

  long hi = r_seed / q;
  long lo = r_seed - q * hi;
  long t = a * lo - r * hi;
      if (t > 0)
          r_seed = t;
      else
          r_seed = t + m;
      return (byte)r_seed;

}

public static void ParkMiller(byte[] arr) {

  byte[] arr = new byte[10900000];
   for (int i = 0; i < arr.Length; i++)
               {                       
                      arr[i] = gen();
               }

}</lang>

ChucK

<lang c> Math.random2(-(Math.random()),Math.random(); </lang>

Common Lisp

<lang lisp>(defun random-int32 ()

 (with-open-file (s "/dev/random" :element-type '(unsigned-byte 32))
   (read-byte s)))</lang>

D

Example of MersenneTwisterEngine for generating uniformly-distributed 32-bit numbers with a period of 2 to the power of 19937. <lang d> import std.stdio; import std.random;

void main() {

 Mt19937 gen;
 gen.seed(unpredictableSeed);
 auto n = gen.front;
 writeln(n);

} </lang>

Output:
run 1: 3500391376
run 2: 9537841895
run 3: 1588499117
run 4: ...

EchoLisp

No random device provided by the host (browser). But we can use the system timer to get a physical input. <lang lisp> (random-seed "simon") (random (expt 2 32)) → 2275215386 (random-seed "simon") (random (expt 2 32)) → 2275215386 ;; the same


(random-seed (current-time-milliseconds )) (random (expt 2 32)) → 4061857345 (random-seed (current-time-milliseconds )) (random (expt 2 32)) → 1322611152 </lang>

Factor

Factor has good support for switching between different random number generators. with-system-random is a combinator that encapsulates the task of using a system RNG (/dev/random in the case of GNU/Linux). <lang factor>USE: random [ random-32 ] with-system-random .</lang>

Forth

<lang 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 ;</lang>

Fortran

Using system /dev/urandom in GNU/Linux.

<lang fortran> !----------------------------------------------------------------------- ! Test Linux urandom in Fortran !----------------------------------------------------------------------- program urandom_test

 use iso_c_binding, only : c_long
 implicit none
 character(len=*), parameter :: RANDOM_PATH = "/dev/urandom"
 integer :: funit, ios
 integer(c_long) :: buf
 open(newunit=funit, file=RANDOM_PATH, access="stream", form="UNFORMATTED", &
      iostat=ios, status="old", action="read")
 if ( ios /= 0 ) stop "Error opening file: "//RANDOM_PATH
 read(funit) buf
 close(funit)
 write(*,'(A,I64)') "Integer:     ", buf
 write(*,'(A,B64)') "Binary:      ", buf
 write(*,'(A,Z64)') "Hexadecimal: ", buf

end program urandom_test </lang>

Here's an example of the use of the latter:

FreeBASIC

FreeBASIC can in theory use any C library to produce pseudo-random numbers including those which are partly device based.

However, in practice, there is little need for this as specifying a second parameter of 5 to FB's Randomize statement produces cryptographically strong pseudo-random numbers using either the Win32 Crypto API or the /dev/urandom device under Linux. <lang freebasic>' FB 1.05.0 Win64

Randomize , 5

'generate 10 cryptographic random integers in the range 1 To 100 For i As Integer = 1 To 10

 Print Int(Rnd * 100) + 1

Next

Sleep</lang>

GlovePIE

<lang glovepie>var.rand=random(10)</lang>

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

}</lang>

Groovy

Based, necessarily, on Java solution: <lang groovy>def rng = new java.security.SecureRandom()</lang>

Test: <lang groovy>(0..4).each { println rng.nextInt() }</lang>

Output:
380425053
-1003791794
-1972330603
1152610574
714616658

Haskell

Library: Entropy
Works with: GHC version 7.4.1

<lang haskell>#!/usr/bin/env 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])</lang>

Icon and Unicon

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

<lang unicon>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</lang>

Sample runs:

->urand
910795827
1135996175
3545606085
944909079
2464790129
->

J

Untested: <lang j>256#.a.i.1!:11'/dev/urandom';0 4</lang>

Fallback: <lang j>256#.a.i.4{.host'dd if=/dev/urandom bs=4 count=1'</lang>

Note: this assumes that J is running on linux.

Java

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

}</lang>

jq

jq does not provide direct access to /dev/urandom, so in the following we assume the availability of `od`, `tr`, and `fold`, and illustrate how to produce an indefinitely long stream of pseudo-random numbers that are approximately uniformly distributed in the range [0,1].

Assuming the jq program shown below is in a file named uniform.jq, the command-line invocation would be:

od -t x -An /dev/urandom | tr -d " " | fold -w 8 | jq -R -f uniform.jq

<lang jq># allow both upper and lower-case characters def hex2integer:

 explode
 | reverse
 | map(if . > 96  then . - 87 elif . > 64 then . - 55 else . - 48 end)
 | reduce .[] as $c
     # state: [power, ans]
     ([1,0]; (.[0] * 16) as $b | [$b, .[1] + (.[0] * $c)])
 | .[1];

select(length>0) | hex2integer / pow(16;length)</lang>

Notice that the program automatically adjusts the precision based on the length of the hexadecimal numbers presented. Since jq uses IEEE 754 64-bit arithmetic, specifying a larger value to `fold`, such as 10, will produce more precise results.

Julia

Works with: Linux

<lang Julia> const rdev = "/dev/random" rstream = try

   open(rdev, "r")

catch

   false

end

if isa(rstream, IOStream)

   b = readbytes(rstream, 4)
   close(rstream)
   i = reinterpret(Int32, b)[1]
   println("A hardware random number is:  ", i)

else

   println("The hardware random number stream, ", rdev, ", was unavailable.")

end </lang>

Output:
A hardware random number is:  986109744

Kotlin

<lang scala>// version 1.1.2

import java.security.SecureRandom

fun main(args: Array<String>) {

   val rng = SecureRandom()
   val rn1 = rng.nextInt()
   val rn2 = rng.nextInt()
   val newSeed = rn1.toLong() * rn2
   rng.setSeed(newSeed)    // reseed using the previous 2 random numbers
   println(rng.nextInt())  // get random 32-bit number and print it

}</lang>

Lasso

<lang lasso>file(`/dev/urandom`)->readSomeBytes(4)->export32bits</lang>

Output:
723217350

M2000 Interpreter

<lang M2000 Interpreter> Module checkit {

     Declare random1 lib "advapi32.SystemFunction036" {long lpbuffer, long length}
     Buffer Clear Alfa as long*2
     Print Eval(Alfa,0)
     Print Eval(Alfa,1)
     call void random1(alfa(0), 8)
     Print Eval(Alfa,0)
     Print Eval(Alfa,1)

} checkit </lang>


<lang M2000 Interpreter> Function Random2 {

     Declare CryptAcquireContext Lib "advapi32.CryptAcquireContextW" {long ByRefhProv,  pszContainer$,pszProvider$, long dwProvType, long dwFlags}
     Declare CryptReleaseContext Lib "advapi32.CryptReleaseContext" {Long hProv, Long dwFlags}
     Declare CryptGenRandom Lib "advapi32.CryptGenRandom" {Long hProv, Long dwLen, Long ByRef}
     Const PROV_RSA_FULL As Long = 1
     Const VERIFY_CONTEXT As Long = 0xF0000000&
     Buffer Clear RandomNum as Long
     Buffer Clear hProv as long
     Call Void CryptAcquireContext( hProv(0), "", "", PROV_RSA_FULL, VERIFY_CONTEXT)
     Call Void CryptGenRandom( Eval(hProv,0), 4, RandomNum(0))
     Call Void CryptReleaseContext(Eval(hProv,0), 0&)
     =Eval(RandomNum,0)

} Print Random2() </lang>

Mathematica

<lang Mathematica>rand32[] := RandomInteger[{-2^31, 2^31 - 1}]</lang>

Example: create array of 10 rand32 numbers <lang Mathematica>Table[rand32[], {i, 1, 10}]</lang>

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

NetRexx

Works with: Mac OS X

and probably other UNIX systems that provide /dev/random or /dev/urandom random data source devices.

<lang NetRexx>/* 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

  • /

</lang>

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
$

Nim

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

OCaml

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

<lang ocaml>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;
</lang>

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

<lang ocaml>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;
</lang>

PARI/GP

It works on systems having /dev/urandom and Linux.

<lang parigp>rnd(n=10)=extern("cat /dev/urandom|tr -dc '[:digit:]'|fold -w"n"|head -1")</lang>

The code above creates a new function rnd() which returns cryptographically strong integers with max. 10 random digits from /dev/urandom. rnd(n) returns integer with max. n random digits. No leading zeros.

Output:
rnd() = 3055652197
rnd(20) = 75735303746547944580
... 

Pascal

This works with FreePascal on "unixoids": <lang pascal>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. </lang>

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

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. <lang Perl>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</lang> or (similar but many more dependencies): <lang Perl>use Crypt::Random::Source qw/get_weak/; # Alternately get_strong print unpack('L*',get_weak(4)), "\n" for 1..10;</lang>

Or we can read values from /dev/urandom ourselves: <lang Perl>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);</lang> 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.

Phix

TODO:

Test once 0.8.0 is released.

My machine does not support the rdrand instruction.
Tested as best I can by commenting out the jnc instructions and replacing rdrand with rdtsc.
I have uploaded replacement pttree.e and pilasm.e (use at your own risk) for anyone wanting to test prior to 0.8.0 being shipped.

If your chip does not support rdrand, you get {1,0}, else {0,-2147483648..2147483647}.
For completeness, I have shown how to convert the signed result to an unsigned one.

<lang Phix>integer res -- 1=failure, 0=success atom rint = 0 -- random 32-bit int

  1. ilASM{
       mov eax,1
       cpuid
       bt ecx,30
       mov edi,1 -- exit code: failure
       jnc :exit
       -- rdrand sets CF=0 if no random number
       -- was available. Intel documentation
       -- recommends 10 retries in a tight loop
       mov ecx,11
   ::loop1
       sub ecx, 1
       jz :exit -- exit code is set already
       rdrand eax
       -- (the above generates exception #C000001D if not supported)

-- rdtsc

       jnc :loop1
       lea edi,[rint]
       call :%pStoreMint
       xor edi,edi
   ::exit
       mov [res],edi
       xor ebx,ebx     -- important!
     }

?{res,rint}

if res=0 then -- (success)

   --
   -- To convert a signed 32-bit int to an unsigned one:
   --
   --  method 1

-- atom urint1 = rint -- if urint1<0 then urint1+=#100000000 end if

   atom urint1 = rint+iff(rint<0?#100000000:0)
   --  method 2
   atom pMem = allocate(4)
   poke4(pMem,rint)
   atom urint2 = peek4u(pMem)
   free(pMem)
   --  method 3
   atom urint3 = bytes_to_int(int_to_bytes(rint,4),signed:=false)
   ?{urint1,urint2,urint3}

end if</lang> A linux-only solution: <lang Phix>integer fn = open("/dev/urandom","rb") if fn=-1 then

   puts(1,"cannot open /dev/urandom\n")

else

   sequence s = {}
   for i=1 to 4 do
       s &= getc(fn)
   end for
   close(fn)
   ?bytes_to_int(s,signed:=false)

end if</lang>

PicoLisp

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

PowerShell

<lang PowerShell> function Get-RandomInteger {

   Param
   (
       [Parameter(Mandatory=$false,
                  ValueFromPipeline=$true,
                  ValueFromPipelineByPropertyName=$true, 
                  Position=0)]
       [ValidateScript({$_ -ge 4})]
       [int[]]
       $InputObject = 64
   )
   Begin
   {
       $rng = New-Object -TypeName System.Security.Cryptography.RNGCryptoServiceProvider
   }
   Process
   {
       foreach($count in $InputObject)
       {
           $bytes = New-Object -TypeName Byte[] -Argument $count
           $rng.GetBytes($bytes)
           [System.BitConverter]::ToInt32($bytes,0)
       }
   }
   End 
   {
       Remove-Variable -Name rng -Scope Local
   }

} </lang> <lang PowerShell> 4,8,16,32,64,128 | Get-RandomInteger | Format-Wide {$_} -Column 6 -Force </lang>

Output:
1402572656             432337086              413089699             1404567509            -82797202             -261009960

As hexadecimal: <lang PowerShell> 4,8,16,32,64,128 | Get-RandomInteger | Format-Wide {"0x{0:X}" -f $_} -Column 6 -Force </lang>

Output:
0x24305255             0x916002DD             0x9587046             0x5F236274            0xC0BAF6F0            0xC0B93118

ProDOS

Uses math module: <lang ProDOS>printline -random- </lang>

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. <lang PureBasic>If OpenCryptRandom()

 MyRandom = CryptRandom(#MAXLONG)
 CloseCryptRandom()

EndIf</lang>

Python

<lang Python>import random rand = random.SystemRandom() rand.randint(1,10)</lang>

Racket

<lang Racket>

  1. lang racket
Assuming a device to provide random bits

(call-with-input-file* "/dev/random"

 (λ(i) (integer-bytes->integer (read-bytes 4 i) #f)))

</lang>

Raku

(formerly Perl 6)

Works with: rakudo version 2016-11

A lazy list of random numbers:

<lang perl6>use experimental :pack; my $UR = open("/dev/urandom", :bin) orelse .die; my @random-spigot = $UR.read(1024).unpack("L*") ... *;

.say for @random-spigot[^10];</lang>

Output:
1431009271
1702240522
670020272
588612037
1864913839
2155430433
1690056587
385405103
2366495746
692037942

REXX

version 1

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. <lang rexx>/*REXX program generates and displays a random 32-bit number using the RANDOM BIF.*/ numeric digits 10 /*ensure REXX has enough decimal digits*/ _=2**16 /*a handy─dandy constant to have around*/ r#= random(0, _-1) * _ + random(0, _-1) /*generate an unsigned 32-bit random #.*/ say r# /*stick a fork in it, we're all done. */</lang>

Output:
4294967296

version 2

This program generates a random 4 byte character string in the range '00000000'x to 'ffffffff'x <lang rexx>left=0 rite=0 lo=hex(left)hex(rite) Say 'low ' c2x(lo) left=random(0,2**16-1) rite=random(0,2**16-1) rand=hex(left)hex(rite) Say 'random' c2x(rand) left=2**16-1 rite=2**16-1 hi=hex(left)hex(rite) Say 'high ' c2x(hi) Exit hex: Return d2c(arg(1),2)</lang>

Output:
low    00000000
random 3E4C3CDE
high   FFFFFFFF

Ring

<lang ring> nr = 10 for i = 1 to nr

   see random(i) + nl

next </lang>

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

<lang Ruby>require 'securerandom' SecureRandom.random_number(1 << 32)</lang>

Rust

rand used to be part of Rust standard library but it was extracted as a 'crate' (https://crates.io/crates/rand). OsRng uses the appropriate device for many platforms including Unix, Windows, BSD, and iOS (listed here). Other methods like RDRAND can be found in other crates (https://crates.io/crates/rdrand).

<lang rust>extern crate rand;

use rand::{OsRng, Rng};

fn main() {

   // because `OsRng` opens files, it may fail
   let mut rng = match OsRng::new() {
       Ok(v) => v,
       Err(e) => panic!("Failed to obtain OS RNG: {}", e)
   };
   let rand_num: u32 = rng.gen();
   println!("{}", rand_num);

}</lang>

Scala

<lang Scala>import java.security.SecureRandom

object RandomExample extends App {

 new SecureRandom {
   val newSeed: Long = this.nextInt().toLong * this.nextInt()
   this.setSeed(newSeed) // reseed using the previous 2 random numbers
   println(this.nextInt()) // get random 32-bit number and print it
 }

}</lang>

Sidef

<lang ruby>func urandom() {

   const device = %f'/dev/urandom';
   device.open('<:raw', \var fh, \var err) ->
       || die "Can't open `#{device}': #{err}";
   fh.sysread(\var noise, 4);
   'L'.unpack(noise);

}

say urandom(); # sample: 3517432564</lang>

Tcl

<lang tcl>package require Tcl 8.5

  1. Allow override of device name

proc systemRandomInteger Template:Device "/dev/random" {

   set f [open $device "rb"]
   binary scan [read $f 4] "I" x
   close $f
   return $x

}</lang> Usage: <lang tcl>% puts [systemRandomInteger] 636131349</lang>

UNIX Shell

<lang UNIX Shell>od -An -N 4 -t u4 /dev/urandom</lang>

Wee Basic

Due to how the code works, any key has to be entered to generate the random number. <lang Wee Basic>let keycode=0 let number=1 print 1 "Press any key to generate a random number from 1 to 10. while keycode=0 let number=number+1 let keycode=key() rem The maximum number is the number in the "if number=" line with 1 taken away. For example, if this number was 11, the maximum number would be 10. * if number=11 let number=1 endif wend print 1 number end</lang>

X86 Assembly

Processors supporting the new RDRAND feature can generate a random 32-bit integer in two instructions: <lang x86>L: rdrand eax jnc L</lang> RDRAND reads the CPU's cryptographically-secure hardware random number generator. The loop is needed because RDRAND can occasionally fail to retrieve a value — it sets the carry flag to indicate whether it succeeded.

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.

<lang XPL0>code Ran=1; int R; R:= Ran($7FFF_FFFF)</lang>

zkl

Translation of: C

Linux: <lang zkl>const RANDOM_PATH="/dev/urandom";

fin,buf:=File(RANDOM_PATH,"r"), fin.read(4); fin.close(); // GC would also close the file println(buf.toBigEndian(0,4)); // 4 bytes @ offset 0</lang>

Output:
2152746403