Skip to content

Commit

Permalink
First version
Browse files Browse the repository at this point in the history
  • Loading branch information
JoakimCh committed May 5, 2021
0 parents commit aa0a749
Show file tree
Hide file tree
Showing 46 changed files with 4,257 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .github/funding.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# These are supported funding model platforms

github: JoakimCh # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: joakimch # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: jlc # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: [buymeacoffee.com/JoakimCh] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
29 changes: 29 additions & 0 deletions examples/deno_runAll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

const scriptDirectory = './'//dirname(fileURLToPath(import.meta.url))+pathSep
const stopOnError = false
let numErrors = 0

const dirents = Deno.readDirSync(scriptDirectory, {withFileTypes: true})
for (const dirent of dirents) {
if (dirent.isFile) {
if (dirent.name.startsWith('example_') && dirent.name.endsWith('.js')) {
console.log('Running '+dirent.name+'... ')
try {
const module = await import(scriptDirectory+dirent.name)
} catch (error) {
console.error(error)
if (stopOnError) {
Deno.exit(1)
}
numErrors ++
}
}
}
}

if (numErrors) {
// Deno.exitCode = 1
console.error('There were '+numErrors+' failed examples!')
} else {
console.log('Done.')
}
3 changes: 3 additions & 0 deletions examples/deno_runAll.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

deno run --import-map=import_map.json --allow-read deno_runAll.js
11 changes: 11 additions & 0 deletions examples/example_1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html><meta charset="utf-8">
<!--script type="importmap" src="import_map.json"></script-->
<script type="importmap">
{
"imports": {
"pluggable-prng": "./node_modules/pluggable-prng/source/pluggablePrng.js"
}
}
</script>
<script type="module" src="example_1.js"></script>
Check your console! :)
121 changes: 121 additions & 0 deletions examples/example_1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@

import {
PluggablePRNG,
RandomGenerator_Alea,
SeedInitializer_Alea,
RandomGenerator_Mulberry32,
RandomGenerator_Sfc32,
RandomGenerator_Pcg32,
SeedInitializer_Uint32,
SeedInitializer_Uint64
} from 'pluggable-prng'

const log = console.log
const wideNumber = new Intl.NumberFormat('fullwide', {maximumSignificantDigits: 21})

log('Alea')
await prngDemoOutput(new PluggablePRNG({
seed: 'Hello World',
RandomGenerator: RandomGenerator_Alea,
SeedInitializer: SeedInitializer_Alea
}))

log('\nMulberry32')
await prngDemoOutput(new PluggablePRNG({
seed: 'Hello World',
RandomGenerator: RandomGenerator_Mulberry32,
SeedInitializer: SeedInitializer_Uint32
}))

log('\nSfc32')
await prngDemoOutput(new PluggablePRNG({
seed: 'Hello World',
RandomGenerator: RandomGenerator_Sfc32,
SeedInitializer: SeedInitializer_Uint32
}))

log('\nPcg32')
await prngDemoOutput(new PluggablePRNG({
seed: 'Hello World',
RandomGenerator: RandomGenerator_Pcg32,
SeedInitializer: SeedInitializer_Uint64
}))

async function prngDemoOutput(prng, iterations=5) {
await prng.readyPromise // if set
log('\nrandomFloat32()')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32()
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat32(4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32(4)
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat32(5,7)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32(5,7)
log(wideNumber.format(n), n.toString(2))
}

log('\nrandomFloat64()')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64()
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat64(4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64(4)
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat64(5,7)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64(5,7)
log(wideNumber.format(n), n.toString(2))
}

log('\nrandomInteger(-0xFFFF_FFFF, 0xFFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(-0xFFFF_FFFF, 0xFFFF_FFFF)
log(n)
}
log('\nrandomInteger(0, 4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, 4)
log(n)
}
log('\nrandomInteger(0, Number.MAX_SAFE_INTEGER)')
log(integerToHex(2**53-1, 8), '== 53 bits all set (Number.MAX_SAFE_INTEGER)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, Number.MAX_SAFE_INTEGER)
log(integerToHex(n, 8))
}
log('\nrandomInteger(0, FF_FFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, 0xFF_FFFF_FFFF)
log(integerToHex(n, 8))
}
log('\nrandomInteger(FFFF_FFFF_0000, FFFF_FFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0xFFFF_FFFF_0000, 0xFFFF_FFFF_FFFF)
log(integerToHex(n, 8))
}
log('\nrandomBytes(100)')
log(await prng.randomBytes(100))
}

function integerToHex(integer, paddingByteSize = 4, grouping = 4) {
let hex = integer.toString(16).toUpperCase()
if (hex.length < paddingByteSize*2)
hex = '0'.repeat((paddingByteSize*2) - hex.length) + hex
if (grouping) {
let result = ''
if (hex.length % grouping) result += hex.slice(0, hex.length % grouping) + '_'
for (let i=hex.length % grouping; i<hex.length; i+=grouping) {
result += hex.slice(i, i+grouping) + '_'
}
hex = result.slice(0, -1)
}
return hex
}
11 changes: 11 additions & 0 deletions examples/example_2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html><meta charset="utf-8">
<!--script type="importmap" src="import_map.json"></script-->
<script type="importmap">
{
"imports": {
"pluggable-prng": "./node_modules/pluggable-prng/source/pluggablePrng.js"
}
}
</script>
<script type="module" src="example_2.js"></script>
Check your console! :)
63 changes: 63 additions & 0 deletions examples/example_2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

import {PluggablePRNG} from 'pluggable-prng'

const log = console.log
const wideNumber = new Intl.NumberFormat('fullwide', {maximumSignificantDigits: 21})

// A dummy generator
function d(...values) {
let i = 0
return new PluggablePRNG({
RandomGenerator: class {
randomUint32() {
if (i == 0) {i++; return 0} // init
if (i == values.length) i = 0
return values[i++] >>> 0
}
},
})
}

log('These functions are ran 3 times with this internal output from a dummy PRNG: [0, 0xFFFF_FFFF/2, 0xFFFF_FFFF]')
log('randomInteger(-0xFFFF_FFFF, 0)')
log(d(0).randomInteger(-0xFFFF_FFFF, 0))
log(d(0xFFFF_FFFF/2).randomInteger(-0xFFFF_FFFF, 0))
log(d(0xFFFF_FFFF).randomInteger(-0xFFFF_FFFF, 0))
log('randomInteger(0, 1)')
log(d(0).randomInteger(0, 1))
log(d(0xFFFF_FFFF/2).randomInteger(0, 1))
log(d(0xFFFF_FFFF).randomInteger(0, 1))
log('randomInteger(-2147483648, 2147483647)')
log(d(0).randomInteger(-2147483648, 2147483647))
log(d(0xFFFF_FFFF/2).randomInteger(-2147483648, 2147483647))
log(d(0xFFFF_FFFF).randomInteger(-2147483648, 2147483647))
log('randomFloat32/64(-0xFFFF_FFFF, 0)')
log(wideNumber.format(d(0).randomFloat32(-0xFFFF_FFFF, 0)))
log(wideNumber.format(d(0).randomFloat64(-0xFFFF_FFFF, 0)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat32(-0xFFFF_FFFF, 0)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat64(-0xFFFF_FFFF, 0)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat32(-0xFFFF_FFFF, 0)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat64(-0xFFFF_FFFF, 0)))
log('randomFloat32/64()')
log(wideNumber.format(d(0).randomFloat32()))
log(wideNumber.format(d(0).randomFloat64()))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat32()))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat64()))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat32()))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat64()))
log('randomFloat32/64(0, 1)')
log(wideNumber.format(d(0).randomFloat32(0, 1)))
log(wideNumber.format(d(0).randomFloat64(0, 1)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat32(0, 1)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat64(0, 1)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat32(0, 1)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat64(0, 1)))
log('randomFloat32/64(1, 2)')
log(wideNumber.format(d(0).randomFloat32(1, 2)))
log(wideNumber.format(d(0).randomFloat64(1, 2)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat32(1, 2)))
log(wideNumber.format(d(0xFFFF_FFFF/2).randomFloat64(1, 2)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat32(1, 2)))
log(wideNumber.format(d(0xFFFF_FFFF).randomFloat64(1, 2)))
log('randomBytes(4*3).reverse().buffer (ran with [0xCAFE_BABE, 0xFA51_F00D, 0xDEAD_BEEF])')
log(d(0xCAFE_BABE, 0xFA51_F00D, 0xDEAD_BEEF).randomBytes(4*3).reverse().buffer)
11 changes: 11 additions & 0 deletions examples/example_web_crypto.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html><meta charset="utf-8">
<!--script type="importmap" src="import_map.json"></script-->
<script type="importmap">
{
"imports": {
"pluggable-prng": "./node_modules/pluggable-prng/source/pluggablePrng.js"
}
}
</script>
<script type="module" src="example_web_crypto.js"></script>
Check your console! :)
97 changes: 97 additions & 0 deletions examples/example_web_crypto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

import {
PluggablePRNG,
RandomGenerator_WebCrypto, SeedInitializer_WebCrypto
} from 'pluggable-prng'

const log = console.log
const wideNumber = new Intl.NumberFormat('fullwide', {maximumSignificantDigits: 21})

if (globalThis.Deno?.version?.deno) {
log('Deno doesn\'t support the Web Crypto API, at least not when I wrote this example...')
} else {
await prngDemoOutput(new PluggablePRNG({
seed: {seed: 0, salt: 'Data to secure the random generator output when a weak (as in short or easy to guess) seed is used.'},
RandomGenerator: RandomGenerator_WebCrypto,
SeedInitializer: SeedInitializer_WebCrypto
}))
}

async function prngDemoOutput(prng, iterations=5) {
await prng.readyPromise // if set
log('\nrandomFloat32()')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32()
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat32(4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32(4)
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat32(5,7)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat32(5,7)
log(wideNumber.format(n), n.toString(2))
}

log('\nrandomFloat64()')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64()
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat64(4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64(4)
log(wideNumber.format(n), n.toString(2))
}
log('\nrandomFloat64(5,7)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomFloat64(5,7)
log(wideNumber.format(n), n.toString(2))
}

log('\nrandomInteger(-0xFFFF_FFFF, 0xFFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(-0xFFFF_FFFF, 0xFFFF_FFFF)
log(n)
}
log('\nrandomInteger(0, 4)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, 4)
log(n)
}
log('\nrandomInteger(0, Number.MAX_SAFE_INTEGER)')
log(integerToHex(2**53-1, 8), '== 53 bits all set (Number.MAX_SAFE_INTEGER)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, Number.MAX_SAFE_INTEGER)
log(integerToHex(n, 8))
}
log('\nrandomInteger(0, FF_FFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0, 0xFF_FFFF_FFFF)
log(integerToHex(n, 8))
}
log('\nrandomInteger(FFFF_FFFF_0000, FFFF_FFFF_FFFF)')
for (let i=0; i<iterations; i++) {
let n = await prng.randomInteger(0xFFFF_FFFF_0000, 0xFFFF_FFFF_FFFF)
log(integerToHex(n, 8))
}
log('\nrandomBytes(100)')
log(await prng.randomBytes(100))
}

function integerToHex(integer, paddingByteSize = 4, grouping = 4) {
let hex = integer.toString(16).toUpperCase()
if (hex.length < paddingByteSize*2)
hex = '0'.repeat((paddingByteSize*2) - hex.length) + hex
if (grouping) {
let result = ''
if (hex.length % grouping) result += hex.slice(0, hex.length % grouping) + '_'
for (let i=hex.length % grouping; i<hex.length; i+=grouping) {
result += hex.slice(i, i+grouping) + '_'
}
hex = result.slice(0, -1)
}
return hex
}
6 changes: 6 additions & 0 deletions examples/import_map.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"imports": {
"pluggable-prng": "./node_modules/pluggable-prng/source/pluggablePrng.js",
"crypto": "node:crypto"
}
}
Loading

0 comments on commit aa0a749

Please sign in to comment.