UNPKG

prng-lfsr

Version:

seedable, seeded, pseudo random number generator, prng, linear feedback shift register, fibonnaci, galois, lfsr

140 lines (104 loc) 3.99 kB
var galois16 = require('../').galois16 , test = require('tape') ; /* START common 16bit lfsr tests */ test('galois16 exists', function (assert) { assert.ok(!!galois16); assert.is('function', typeof galois16); assert.end(); }); test('galois16 rejects bad seeds', function (assert) { assert.is(galois16(), false, 'mandatory seed!'); assert.is(galois16('foo'), false); assert.is(galois16(function () {}), false); assert.is(galois16({}), false); assert.is(galois16([]), false); assert.is(galois16(65536), false); assert.is(galois16(-1), false); assert.is(galois16(0), false); assert.end(); }); test('galois16 returns a function if seed ok', function (assert) { assert.is(typeof galois16(1), 'function'); assert.is(typeof galois16(2), 'function'); assert.is(typeof galois16(65535), 'function'); assert.is(typeof galois16(0xACE1), 'function'); assert.end(); }); test('galois16 has expected periodicity', function (assert) { var seed = 0xACE1 , g = galois16(seed) , remainingIterations = 0xffff // 65535 iterations to return to start , lastResult ; while (remainingIterations--) { if (seed === lastResult) { assert.ok(false, 'found seed value too early! remainingIterations: ' + remainingIterations) }; lastResult = g(); } assert.is(lastResult, seed, '0xACE1 -------> 0xACE1 after maximum iterations'); assert.end(); }); test('galois16 output bit stream', function (assert) { var seed = 0xACE1 , g = galois16(seed) , remainingIterations = 0xffff // 65535 iterations to return to start. aka (2^n)-1 , lastResult , bitString = '' , maxZeroRun = /000000000000000/g // n - 1 , impossibleZeroRun = /0000000000000000/g // n , maxOneRun = /1111111111111111/g // n , impossibleOneRun = /11111111111111111/g // n + 1 , found ; while (remainingIterations--) { lastResult = g(); bitString += lastResult & 1; // right-most bit is output bit. NB. different output bit to fibonacci } assert.is(bitString.length, 0xffff, 'got right number of bits'); found = maxZeroRun.exec(bitString); assert.is(found.length, 1, 'got right number of maximum runs of 0'); found = impossibleZeroRun.exec(bitString); assert.is(found, null, 'got no runs of 0 exceeding n'); found = maxOneRun.exec(bitString); assert.is(found.length, 1, 'got right number of maximum runs of 1'); found = impossibleOneRun.exec(bitString); assert.is(found, null, 'got no runs of 1 exceeding n'); assert.end(); }); /* END common 16bit lfsr tests */ test('galois16 returns successful next values', function (assert) { var g = galois16(0xACE1); assert.is(g(), 0xE270, '0xACE1 -> 0xE270'); assert.is(g(), 0x7138, '0xE270 -> 0x7138'); assert.end(); }); test('galois/fibonacci output bit stream equivalance', function (assert) { // TODO this shouldn't live here! move to common tests var fibonacci16 = require('../').fibonacci16; var seed = 0xACE1 , g = galois16(seed) , f = fibonacci16(seed) , gLastResult , galoisBitString = '' , fLastResult , fibonacciBitString = '' , fibonacciOffset = 14077 , remainingIterations = 0xffff // 65535 iterations to return to start. aka (2^n)-1 ; /* shows offset at 14077 ... is this right? //console.log(fibonacciBitString.indexOf(galoisBitString.substr(0,256))); if so then formalising a test that warms up fibonnacci, then we shall test equality */ while (fibonacciOffset--) { f(); } while (remainingIterations--) { gLastResult = g(); fLastResult = f(); galoisBitString += gLastResult & 1; // right-most bit is output bit. NB. different output bit to fibonacci fibonacciBitString += (fLastResult >> 15) & 1; // left-most bit is last output bit. NB. different output bit to galois } assert.is(galoisBitString, fibonacciBitString, 'galoisBitString === fibonacciBitString'); // wow, it works. assert.end(); });