diff --git a/lib/uuid.js b/lib/uuid.js index f616d52..1963639 100644 --- a/lib/uuid.js +++ b/lib/uuid.js @@ -21,26 +21,33 @@ UUIDjs.limitUI32 = UUIDjs.maxFromBits(32); UUIDjs.limitUI40 = UUIDjs.maxFromBits(40); UUIDjs.limitUI48 = UUIDjs.maxFromBits(48); +// Returns a random integer between min and max +// Using Math.round() will give you a non-uniform distribution! +// @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/random +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + UUIDjs.randomUI04 = function() { - return Math.round(Math.random() * UUIDjs.limitUI04); + return getRandomInt(0, UUIDjs.limitUI04-1); }; UUIDjs.randomUI06 = function() { - return Math.round(Math.random() * UUIDjs.limitUI06); + return getRandomInt(0, UUIDjs.limitUI06-1); }; UUIDjs.randomUI08 = function() { - return Math.round(Math.random() * UUIDjs.limitUI08); + return getRandomInt(0, UUIDjs.limitUI08-1); }; UUIDjs.randomUI12 = function() { - return Math.round(Math.random() * UUIDjs.limitUI12); + return getRandomInt(0, UUIDjs.limitUI12-1); }; UUIDjs.randomUI14 = function() { - return Math.round(Math.random() * UUIDjs.limitUI14); + return getRandomInt(0, UUIDjs.limitUI14-1); }; UUIDjs.randomUI16 = function() { - return Math.round(Math.random() * UUIDjs.limitUI16); + return getRandomInt(0, UUIDjs.limitUI16-1); }; UUIDjs.randomUI32 = function() { - return Math.round(Math.random() * UUIDjs.limitUI32); + return getRandomInt(0, UUIDjs.limitUI32-1); }; UUIDjs.randomUI40 = function() { return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 40 - 30)) * (1 << 30); diff --git a/test/uuid.js b/test/uuid.js index c028d70..c37527e 100644 --- a/test/uuid.js +++ b/test/uuid.js @@ -329,6 +329,25 @@ exports['newTS() alias for create(1)'] = function() { spy.restore(); }; +exports['correct random max values'] = function() { + + var stub = sinon.stub(Math, 'random').returns(0.9999999999); + + assert.equal(UUID.randomUI04(), 0x0000000F); + assert.equal(UUID.randomUI06(), 0x0000003F); + assert.equal(UUID.randomUI08(), 0x000000FF); + assert.equal(UUID.randomUI12(), 0x00000FFF); + assert.equal(UUID.randomUI14(), 0x00003FFF); + assert.equal(UUID.randomUI16(), 0x0000FFFF); + assert.equal(UUID.randomUI32(), 0xFFFFFFFF); + + // not really sure about these.... + assert.equal(UUID.randomUI40(), 0xFFFFFFFFFF); + assert.equal(UUID.randomUI48(), 0xFFFFFFFFFFFF); + + stub.restore(); + +}; for (var key in exports) { exports[key]();