Last active
September 21, 2016 21:47
-
-
Save sammoore/9896896e63f32720522db6f66eabc7c1 to your computer and use it in GitHub Desktop.
(BROKEN) A basic PRNG for client-side / web pages, which either resolves the RandomSource / Crypto object from the global Window, otherwise uses a sketchy, cryptographically insecure generator based on Math.random. Do not use this unless you don't need cryptographically secure randomness.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sam's PRNG "proxy" for client-side JS, which generates random `UInt32`'s. | |
// Attempts to resolve the window's Crypto object and use its getRandomValues | |
// function if available, otherwise provides a cryptographically insecure PRN | |
// based on combining the current time and Math.random(). | |
// | |
// Note: if any truthy argument is provided, the Fallback impl. will be used. | |
// otherwise, attempts to use the Window's Crypto object if possible. | |
// Usage: | |
/// var prng = SMPRNG(); | |
/// var uint = prng.next(); | |
var SMPRNG = function(fallback) { | |
// Returns a psuedo-random UInt32 generator. | |
// For use if a WindowRandomGenerator can not be constructed. | |
FallbackRandomGen = (function() { | |
_epoch = new Date().getTime(); | |
_min = 1; | |
_max = Math.pow(2, 32); | |
// XOR's the input value in an attempt to avoid duplicates from poor | |
// seed values using the current time in milliseconds from the UNIX epoch. | |
_obfuscate = function(val) { | |
_epoch += 1; | |
return val ^ _epoch; | |
}; | |
// Returns a value between the given min (inclusive) and max (exclusive) | |
// based on the provided value. | |
_limitToRange = function(val, min, max) { | |
min = Math.ceil(min); | |
max = Math.floor(max); | |
return Math.floor(val * (max - min) + min); | |
}; | |
return { | |
'next': function() { | |
rand = _obfuscate(Math.random()) >>> 1; | |
return _limitToRange(rand, _min, _max); | |
} | |
}; | |
}); | |
// If the fallback was requested | |
if (fallback !== undefined && fallback != false) { | |
return FallbackRandomGen(); | |
} | |
// Constructs a random UInt32 generator based on a getRandomValues function. | |
// SeeAlso: https://developer.mozilla.org/en-US/docs/Web/API/RandomSource | |
WindowRandomGen = (function(getRandomValues) { | |
source = { | |
'getRandomValues': getRandomValues | |
}; | |
return { | |
'next': function() { | |
array = new Uint32Array(1); | |
source.getRandomValues(array); | |
return array[0]; | |
} | |
} | |
}); | |
// Provide the Window's backing impl. if possible, otherwise the fallback. | |
cryptoObj = (window.crypto || window.msCrypto) || {}; | |
getRandomValues = cryptoObj.getRandomValues; | |
if (typeof(getRandomValues) === 'function') { | |
return WindowRandomGen(getRandomValues); | |
} else { | |
return FallbackRandomGen(); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment