prng-lfsr
Version:
seedable, seeded, pseudo random number generator, prng, linear feedback shift register, fibonnaci, galois, lfsr
82 lines (66 loc) • 2.32 kB
JavaScript
// KLUDGEZONE - temporary code below.
// Offer a rudimentary RBG (Random Bit Generator) for piping the relevant outputBit to dieharder and the like...
// NB. no unit tests as yet, expect to move/replace this api in future.
// TODO consider offering the full PRNG output as:
// 1) a numeric stream - 0xACE1
// 2) a hex digest stream 'ACE1'
// 3) a complete bit stream 0110010101010010100...
// ...etc. etc. etc...
// If so, should NOT live here anyway! ;)
// See example/prng-lfsr-stream.js for usage
var prngLFSR = require('../')
, fibonacci16 = prngLFSR.fibonacci16
, galois16 = prngLFSR.galois16
, kludgeyStream = (function () {
var util = require('util')
, stream = require('stream')
, RBGStream = function RBGStreamConstructor() {
this.readable = true;
this.writable = true;
}
;
util.inherits(RBGStream, stream);
RBGStream.prototype.write = function RBGStreamProtoWrite(data, outputBitOffsetFromLSB) {
// select the relevant outputBit
this.emit('data', new Buffer((data >> outputBitOffsetFromLSB) & 1, 'binary'));
// this.emit('data', new Buffer(data, 'binary'));
};
RBGStream.prototype.end = function RBGStreamProtoEnd() {
this.emit('end');
};
// kludgey augmenting of lfsr types with outputBit offset, this IS temporary, yeh!
// |0110011010010101|
// | 3<--|
fibonacci16.outputBitOffset = 15;
galois16.outputBitOffset = 0;
return function (prngType, seed, destination) {
var wrapper
, prng
, rbg
// saves typing fibonnaci wrong... ahem. (yes, i will remove it and inject prng instead)
, validTypes = {
'FIB16': fibonacci16,
'GAL16': galois16
}
// rudimentary guarding
if ( !prngType
|| !validTypes[prngType]
|| !(prng = validTypes[prngType](seed))
|| !destination) return false;
rbg = new RBGStream();
rbg.pipe(destination);
wrapper = function wrapperNext() {
var prngState = prng();
rbg.write(prngState, prng.outputBitOffset);
return prngState;
};
// allow instance.end();
wrapper.end = function () {
rbg.end();
};
// whenever wrapper is invoked the next state will be piped to destination
return wrapper;
};
}());
;
module.exports = kludgeyStream;