I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Pseudorandom Number Generator Image

From Rosetta Code
Pseudorandom Number Generator Image is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Write a program that creates an image from a Pseudorandom Number Generator (PRNG) algorithm's output. The image can have the following dimensions:

  1. 250px by 250px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
  2. 500px by 500px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
  3. 1000px by 1000px : If the algorithm requires the use of prime numbers, use 8-32 bit primes.
  4. 1500px by 1500px : If the algorithm requires the use of prime numbers, use 16-64 bit primes.
Possible Output

https://www.random.org/analysis/randbitmap-rdo.png

https://ibb.co/ZJPS16j

See also
  •   Blum Blum Shub [1].
  •   Blum-Micali Algorithm: [2].
  •   Linear congruential generator [3].


Go[edit]

The math/rand package uses a custom algorithm attributed to D.P.Mitchell and J.A.Reeds. It doesn't need to be seeded by a prime number. Typically (as here) the seed is generated from the current time.

The image is saved to a .png file which can then be viewed with a utility such as EOG.

package main
 
import (
"image"
"image/color"
"image/png"
"log"
"math/rand"
"os"
"time"
)
 
func main() {
rand.Seed(time.Now().UnixNano())
img := image.NewNRGBA(image.Rect(0, 0, 1000, 1000))
for x := 0; x < 1000; x++ {
for y := 0; y < 1000; y++ {
col := color.RGBA{uint8(rand.Intn(256)), uint8(rand.Intn(256)), uint8(rand.Intn(256)), 255}
img.Set(x, y, col)
}
}
fileName := "pseudorandom_number_generator.png"
imgFile, err := os.Create(fileName)
if err != nil {
log.Fatal(err)
}
defer imgFile.Close()
 
if err := png.Encode(imgFile, img); err != nil {
imgFile.Close()
log.Fatal(err)
}
}

Java[edit]

Following implementation generates images from java.util.Random(uses linear congruential generator [4].) and Blum Blum Shub Algorithm with least significant bit method and even bit parity method[5].

 
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
import java.util.Scanner;
/*
* Numbers to try:
* p = 11 or BigInteger.probablePrime(BIT1_LENGTH, rand)
* q = 23 or BigInteger.probablePrime(BIT_LENGTH, rand)
* seed = 3 or BigInteger.probablePrime(BIT_LENGTH,rand)
* */

 
public class csprngBBS {
public static Scanner input = new Scanner(System.in);
private static final String fileformat = "png";
private static String bitsStri = "";
private static String parityEven = "";
private static String leastSig = "";
private static String randomJavaUtil = "";
private static int width = 0;
private static int BIT_LENGTH = 0;
private static final Random rand = new SecureRandom();
private static BigInteger p = null; // 11
private static BigInteger q = null; // 23
private static BigInteger m = null;
private static BigInteger seed = null; // 3
private static BigInteger seedFinal = null;
private static final Random randMathUtil = new SecureRandom();
public static void main(String[] args) throws IOException {
System.out.print("Width: ");
width = input.nextInt();
System.out.print("Bit-Length: ");
BIT_LENGTH = input.nextInt();
System.out.print("Generator format: ");
String useGenerator = input.next();
p = BigInteger.probablePrime(BIT_LENGTH, rand);
q = BigInteger.probablePrime(BIT_LENGTH, rand);
m = p.multiply(q);
seed = BigInteger.probablePrime(BIT_LENGTH,rand);
seedFinal = seed.add(BigInteger.ZERO);
if(useGenerator.contains("parity") && useGenerator.contains("significant")) {
findLeastSignificant();
findBitParityEven();
createImage(parityEven, "parityEven");
createImage(leastSig, "significant");
}
 
if(useGenerator.contains("parity") && !useGenerator.contains("significant")){
findBitParityEven();
}
 
if(useGenerator.contains("significant") && !useGenerator.contains("parity")){
findLeastSignificant();
createImage(leastSig, "significant");
}
 
if(useGenerator.contains("util")){
findRandomJava(randMathUtil);
createImage(randomJavaUtil, "randomUtilJava");
}
}
public static void findRandomJava(Random random){
for(int x = 1; x <= Math.pow(width, 2); x++){
randomJavaUtil += random.nextInt(2);
}
}
 
public static void findBitParityEven(){
for(int x = 1; x <= Math.pow(width, 2); x++) {
seed = seed.pow(2).mod(m);
bitsStri = convertBinary(seed);
char[] bits = bitsStri.toCharArray();
int counter = 0;
for (char bit : bits) {
if (bit == '1') {
counter++;
}
}
if (counter % 2 != 0) {
parityEven += "1";
} else {
parityEven += "0";
}
}
}
 
public static void findLeastSignificant(){
seed = seedFinal;
for(int x = 1; x <= Math.pow(width, 2); x++){
seed = seed.pow(2).mod(m);
leastSig += bitsStri.substring(bitsStri.length() - 1);
}
}
 
public static String convertBinary(BigInteger value){
StringBuilder total = new StringBuilder();
BigInteger two = BigInteger.TWO;
while(value.compareTo(BigInteger.ZERO) > 0){
total.append(value.mod(two));
value = value.divide(two);
}
return total.reverse().toString();
}
 
public static void createImage(String useThis, String fileName) throws IOException {
int length = csprngBBS.width;
// Constructs a BufferedImage of one of the predefined image types.
BufferedImage bufferedImage = new BufferedImage(length, length, 1/*BufferedImage.TYPE_INT_RGB*/);
// Create a graphics which can be used to draw into the buffered image
Graphics2D g2d = bufferedImage.createGraphics();
for (int y = 1; y <= length; y++) {
for (int x = 1; x <= length; x++) {
if (useThis.startsWith("1")) {
useThis = useThis.substring(1);
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 1, 1);
} else if (useThis.startsWith("0")) {
useThis = useThis.substring(1);
g2d.setColor(Color.WHITE);
g2d.fillRect(x, y, 1, 1);
}
}
System.out.print(y + "\t");
}
// Disposes of this graphics context and releases any system resources that it is using.
g2d.dispose();
// Save as file
File file = new File("REPLACEFILEPATHHERE" + fileName + "." + fileformat);
ImageIO.write(bufferedImage, fileformat, file);
}
}
 

Julia[edit]

Julia uses the Mersenne Twister algorithm for its default rand() function. That algorithm uses over 600 32-bit ints to represent its internal state, rather than just a product of two or three primes.

using FileIO, ImageIO
 
save("randombw.png", rand(Float16, 1000, 1000))
 

Perl[edit]

Perl unified the PRNG with its own internal drand48() implementation on all platforms since v5.20.0. Without a manual srand, Perl by default source the seed from "/dev/urandom" if it is available so there shouldn't be any prime prerequisite.

use strict;
use warnings;
use GD;
 
my $img = new GD::Image(500, 500, 1);
 
for my $y(0..500) {
for my $x(0..500) {
my $color = $img->colorAllocate(rand 256, rand 256, rand 256);
$img->setPixel($x, $y, $color);
}
}
 
open F, "image500.png";
print F $img->png;

image500.png (sample image, offsite)

PicoLisp[edit]

(seed (in "/dev/urandom" (rd 8)))
(out "image.pbm"
(prinl "P1")
(prinl 500 " " 500)
(do 500
(do 500
(prin (if (rand T) 1 0)) )
(prinl) ) )

Raku[edit]

MoarVM uses Mersenne Twister as its PRNG but a prime seeder is not mandatory.

# 20200818 Raku programming solution
 
use Image::PNG::Portable;
 
srand 2⁶³ - 25; # greatest prime smaller than 2⁶³ and the max my system can take
 
my @data = < 250 500 1000 1500 >;
 
@data.map: {
my $o = Image::PNG::Portable.new: :width($_), :height($_);
for ^$_ X ^$_ -> @pixel { # about 40% slower if split to ($x,$y) or (\x,\y)
$o.set: @pixel[0], @pixel[1], 256.rand.Int, 256.rand.Int, 256.rand.Int
}
$o.write: "image$_.png" or die;
}
Output:
file image*.png
image1000.png: PNG image data, 1000 x 1000, 8-bit/color RGBA, non-interlaced
image1500.png: PNG image data, 1500 x 1500, 8-bit/color RGBA, non-interlaced
image250.png:  PNG image data, 250 x 250, 8-bit/color RGBA, non-interlaced
image500.png:  PNG image data, 500 x 500, 8-bit/color RGBA, non-interlaced

image500.png (sample image, offsite)

Wren[edit]

Library: DOME

Wren's 'random' module uses the 'Well equidistributed long-period linear' (WELL512a) PRNG which doesn't need to be seeded with a prime number. It is in fact seeded from a sequence of 16 numbers but, if less are provided, the others are generated automatically. Typically (as here) the seed is generated from the current time.

import "dome" for Window
import "graphics" for Canvas, Color
import "random" for Random
 
class Game {
static init() {
Window.title = "Pseudorandom Number Generator Image"
Window.resize(1000, 1000)
Canvas.resize(1000, 1000)
var r = Random.new() // generates seed from current time
for (x in 0...1000) {
for (y in 0...1000) {
var c = Color.rgb(r.int(256), r.int(256), r.int(256))
Canvas.pset(x, y, c)
}
}
}
 
static update() {}
 
static draw(dt) {}
}