Pseudorandom number generator image: Difference between revisions
(Added Sidef) |
|||
Line 390: | Line 390: | ||
</pre> |
</pre> |
||
[https://github.com/SqrtNegInf/Rosettacode-Perl6-Smoke/blob/master/ref/PNG-image500.png image500.png] (sample image, offsite) |
[https://github.com/SqrtNegInf/Rosettacode-Perl6-Smoke/blob/master/ref/PNG-image500.png image500.png] (sample image, offsite) |
||
=={{header|Sidef}}== |
|||
{{trans|Perl}} |
|||
<lang ruby>require('GD') |
|||
var img = %O<GD::Image>.new(500, 500, 1) |
|||
for y in (0..500), x in (0..500) { |
|||
var color = img.colorAllocate(255.irand, 255.irand, 255.irand) |
|||
img.setPixel(x, y, color) |
|||
} |
|||
File("image500.png").write(img.png, :raw)</lang> |
|||
=={{header|Wren}}== |
=={{header|Wren}}== |
Revision as of 20:58, 5 July 2021
- Task
Write a program that creates an image from a Pseudorandom Number Generator (PRNG) algorithm's output. The image can have the following dimensions:
- 250px by 250px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
- 500px by 500px : If the algorithm requires the use of prime numbers, use 8-15 bit primes.
- 1000px by 1000px : If the algorithm requires the use of prime numbers, use 8-32 bit primes.
- 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
- See also
Delphi
<lang Delphi> program Pseudorandom_number_generator_image;
{$APPTYPE CONSOLE}
uses
System.SysUtils, vcl.Graphics, Vcl.Imaging.PngImage;
type
TRGBTriple = packed record b: Byte; g: Byte; r: Byte; end;
PRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = array[0..999] of TRGBTriple;
function Noise(cWidth, cHeight: Integer; Color: boolean = True): TBitmap; const
Seed = 2147483647;
var
Pixels: PRGBTripleArray;
begin
RandSeed := Seed; Result := TBitmap.Create; with Result do begin SetSize(cWidth, cHeight); PixelFormat := pf24bit; for var row := 0 to cHeight - 1 do begin Pixels := ScanLine[row]; for var col := 0 to cWidth - 1 do begin if Color then begin Pixels[col].r := random(255); Pixels[col].g := random(255); Pixels[col].b := random(255); end else begin var Gray := Round((0.299 * random(255)) + (0.587 * random(255)) + (0.114 * random(255))); Pixels[col].r := Gray; Pixels[col].g := Gray; Pixels[col].b := Gray; end; end; end; end;
end;
const
cWidth = 1000; cHeight = 1000;
begin
// Color noise var bmp := Noise(cWidth, cHeight); bmp.SaveToFile('randbitmap-rdo.bmp');
// to Png with TPngImage.create do begin Assign(bmp); SaveToFile('randbitmap-rdo.png'); free; end; bmp.Free;
// Gray noise bmp := Noise(cWidth, cHeight, False); bmp.SaveToFile('randbitmap-rdo_g.bmp');
// to Png with TPngImage.create do begin Assign(bmp); SaveToFile('randbitmap-rdo_g.png'); free; end; bmp.Free;
end.</lang>
- Output:
Go
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. <lang go>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) }
}</lang>
Java
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]. <lang Java> 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); }
} </lang>
Julia
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. <lang julia>using FileIO, ImageIO
save("randombw.png", rand(Float16, 1000, 1000)) </lang>
Nim
Nim standard PRNG is an implementation of the xoroshiro128+
(xor/rotate/shift/rotate) algorithm which is extremely fast. The standard library provides a Mersenne Twister implementation too. For this task, we used the first one.
<lang Nim>import random import imageman
const Size = 500
randomize() var image = initImage[ColorRGBU](Size, Size) for x in 0..<Size:
for y in 0..<Size: let color = ColorRGBU([rand(255).byte, rand(255).byte, rand(255).byte]) image[x, y] = color
image.savePNG("prng_image.png", compression = 9)</lang>
Perl
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. <lang perl>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;</lang> image500.png (sample image, offsite)
Phix
<lang Phix>-- demo\rosetta\Pseudorandom_number_generator_image.exw include pGUI.e
IupOpen() integer w=250, h=w sequence bw = repeat(0,w*h) for x=0 to w-1 do
for y=0 to h-1 do if rand(2)=2 then bw[x*h+y+1] = 255 end if end for
end for Ihandle image = IupImage(w,h,bw) object res = IupSaveImage(image,"bw.png","PNG") IupClose()</lang>
PicoLisp
<lang PicoLisp>(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) ) )</lang>
Raku
MoarVM uses Mersenne Twister as its PRNG but a prime seeder is not mandatory. <lang perl6># 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;
}</lang>
- 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)
Sidef
<lang ruby>require('GD')
var img = %O<GD::Image>.new(500, 500, 1)
for y in (0..500), x in (0..500) {
var color = img.colorAllocate(255.irand, 255.irand, 255.irand) img.setPixel(x, y, color)
}
File("image500.png").write(img.png, :raw)</lang>
Wren
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. <lang ecmascript>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) {}
}</lang>