Task

If your system has a means to generate random numbers involving not only a software algorithm (like the [[wp:/dev/random|/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.

.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




## Ada

random.adb:

```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;

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


Batch File

The dynamic environmental variable %random% contains a number between 0 and 32767.


@echo %random%

BBC BASIC

Requires Windows XP or later.

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

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

=== {{libheader|BSD libc}} === [http://www.openbsd.org/cgi-bin/man.cgi?query=arc4random&apropos=0&sektion=3&manpath=OpenBSD+Current&arch=i386&format=html 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;
}

=== {{libheader|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 [http://egd.sourceforge.net/ 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;
}

Windows

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

== {{header|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)#C.2B.2B|Random number generator (included)]] for the list of pseudo-random number engines available.

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

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

Park-Miller random number generator


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

== {{header|ChucK}} ==

 Math.random2(-(Math.random()),Math.random();

Common Lisp

(defun random-int32 ()
  (with-open-file (s "/dev/random" :element-type '(unsigned-byte 32))
    (read-byte s)))

D

Example of MersenneTwisterEngine for generating uniformly-distributed 32-bit numbers with a period of 2 to the power of 19937.


import std.stdio;
import std.random;

void main()
{
  Mt19937 gen;
  gen.seed(unpredictableSeed);
  auto n = gen.front;
  writeln(n);
}


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.


(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

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

USE: random
[ random-32 ] with-system-random .

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 ;

Fortran

Using system /dev/urandom in [[GNU]]/[[Linux]].


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

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.

' 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

GlovePIE

var.rand=random(10)

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

Groovy

Based, necessarily, on Java solution:

def rng = new java.security.SecureRandom()

Test:

(0..4).each { println rng.nextInt() }
380425053
-1003791794
-1972330603
1152610574
714616658

=={{header|Icon}} and {{header|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
->

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.

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

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

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


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


A hardware random number is:  986109744

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

Kotlin

// 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
}

Lasso

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

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


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

Mathematica

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

Example: create array of 10 rand32 numbers

Table[rand32[], {i, 1, 10}]
{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.

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


$ 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

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

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

PARI/GP

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

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

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.


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

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.


>: ./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.

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.

Perl 6

A lazy list of random numbers:

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

.say for @random-spigot[^10];
1431009271
1702240522
670020272
588612037
1864913839
2155430433
1690056587
385405103
2366495746
692037942

Phix

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.

integer res  -- 1=failure, 0=success
atom rint = 0   -- random 32-bit int

#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

A linux-only solution:

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

PicoLisp

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

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


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


1402572656             432337086              413089699             1404567509            -82797202             -261009960

As hexadecimal:


4,8,16,32,64,128 | Get-RandomInteger | Format-Wide {"0x{0:X}" -f $_} -Column 6 -Force


0x24305255             0x916002DD             0x9587046             0x5F236274            0xC0BAF6F0            0xC0B93118

ProDOS

Uses math module:

printline -random-

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

Python

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

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

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.

/*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. */

4294967296

version 2

This program generates a random 4 byte character string in the range '00000000'x to 'ffffffff'x

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)
low    00000000
random 3E4C3CDE
high   FFFFFFFF

Ring


nr = 10
for i = 1 to nr
    see random(i) + nl
next

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.

require 'securerandom'
SecureRandom.random_number(1 << 32)

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 [https://docs.rs/rand/0.4/rand/os/struct.OsRng.html here]). Other methods like RDRAND can be found in other crates (https://crates.io/crates/rdrand).

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

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

Sidef

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

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

UNIX Shell

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

Wee Basic

Due to how the code works, any key has to be entered to generate the random number.

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

X86 Assembly

Processors supporting the new RDRAND feature can generate a random 32-bit integer in two instructions:

L: rdrand eax
jnc L

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.

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

zkl

Linux:

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

2152746403