Skip to content

Instantly share code, notes, and snippets.

@sammoore
Last active September 21, 2016 21:47
Show Gist options
  • Save sammoore/9896896e63f32720522db6f66eabc7c1 to your computer and use it in GitHub Desktop.
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.
// 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