Skip to content

Commit

Permalink
uuid versions into separate modules, per #154 (#159)
Browse files Browse the repository at this point in the history
uuid versions into separate modules, per #154
  • Loading branch information
broofa authored Nov 26, 2016
1 parent 3c7bec9 commit 681bddd
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 84 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
node_modules
.DS_Store

# VIM temp files
*.sw*

# Mac desktop services store
.DS_Store
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,40 @@ Features:
* Generate RFC4122 version 1 or version 4 UUIDs
* Runs in node.js and browsers
* Cryptographically strong random number generation on supporting platforms
* Small footprint (Want something smaller? [Check this out](https://gist.github.com/982883) out!)
* Small footprint (Want something smaller? [Check this out](https://gist.github.com/982883)!)

## Quickstart - nodejs
## Quickstart - CommonJS (Recommended)

```shell
npm install uuid
```

```javascript
const uuid = require('uuid');
// Generate a v1 UUID (time-based)
const uuidV1 = require('uuid/v1');
uuidV1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'

// Generate a v4 (random) id
uuid() // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

// Generate a v1 (time-based) id
uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
// Generate a v4 UUID (random)
const uuidV4 = require('uuid/v4');
uuidV4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
```

## Quickstart - browser

**Not recommended for production or even semi-production use. Use a bundling tool instead (i.e. webpack, browserify, rollup, etc)**
## Quickstart - Pre-packaged for browsers (Not recommended)

[wzrd.in](https://github.com/jfhbrook/wzrd.in) will serve up any npm module after performing basic bundling and minification.
Browser-ready versions of this module are available via [wzrd.in](https://github.com/jfhbrook/wzrd.in).

```html
<script src="http://wzrd.in/standalone/uuid@latest"></script>

<script>
uuid.v1(); // -> v1 UUID
uuid.v4(); // -> v4 UUID
</script>
```

(Note: Do not do this in production. Just don't. wzrd.in is a great service, but if you're deploying a "real" service you should be using a packaging tool like browserify or webpack. If you do go this route you would be well advised to link to a specific version instead of `uuid@latest` to avoid having your code break when we roll out breaking changes.)


## API

### uuid(...)
Expand Down
8 changes: 8 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var v1 = require('./v1');
var v4 = require('./v4');

var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;

module.exports = uuid;
23 changes: 23 additions & 0 deletions lib/bytesToUuid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}

function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}

module.exports = bytesToUuid;
21 changes: 11 additions & 10 deletions lib/rng-browser.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@

// Unique ID creation requires a high quality random # generator. In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API. We do the best we can via
// feature-detection
var rng;

var crypto = global.crypto || global.msCrypto; // for IE 11
if (crypto && crypto.getRandomValues) {
// WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
// Moderately fast, high quality
var _rnds8 = new Uint8Array(16);
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
var rnds8 = new Uint8Array(16);
rng = function whatwgRNG() {
crypto.getRandomValues(_rnds8);
return _rnds8;
crypto.getRandomValues(rnds8);
return rnds8;
};
}

Expand All @@ -17,16 +19,15 @@ if (!rng) {
//
// If all else fails, use Math.random(). It's fast, but is of unspecified
// quality.
var _rnds = new Array(16);
var rnds = new Array(16);
rng = function() {
for (var i = 0, r; i < 16; i++) {
if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
_rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
}

return _rnds;
return rnds;
};
}

module.exports = rng;

8 changes: 7 additions & 1 deletion lib/rng.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// Unique ID creation requires a high quality random # generator. In node.js
// this is prett straight-forward - we use the crypto API.

var rb = require('crypto').randomBytes;
module.exports = function() {

function rng() {
return rb(16);
};

module.exports = rng;
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"rfc4122"
],
"license": "MIT",
"main": "./uuid.js",
"bin": {
"uuid": "./bin/uuid"
},
Expand All @@ -25,4 +24,4 @@
"type": "git",
"url": "https://github.com/kelektiv/node-uuid.git"
}
}
}
64 changes: 5 additions & 59 deletions uuid.js → v1.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,16 @@
// Unique ID creation requires a high quality random # generator. We feature
// detect to determine the best RNG source, normalizing to a function that
// returns 128-bits of randomness, since that's what's usually required
var _rng = require('./lib/rng');

// Maps for number <-> hex string conversion
var _byteToHex = [];
var _hexToByte = {};
for (var i = 0; i < 256; ++i) {
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
_hexToByte[_byteToHex[i]] = i;
}

function buff_to_string(buf, offset) {
var i = offset || 0;
var bth = _byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');

// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html

// random #'s we need to init node and clockseq
var _seedBytes = _rng();
var _seedBytes = rng();

// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
var _nodeId = [
Expand Down Expand Up @@ -117,41 +97,7 @@ function v1(options, buf, offset) {
b[i + n] = node[n];
}

return buf ? buf : buff_to_string(b);
return buf ? buf : bytesToUuid(b);
}

// **`v4()` - Generate random UUID**

// See https://github.com/broofa/node-uuid for API details
function v4(options, buf, offset) {
// Deprecated - 'format' argument, as supported in v1.2
var i = buf && offset || 0;

if (typeof(options) == 'string') {
buf = options == 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};

var rnds = options.random || (options.rng || _rng)();

// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;

// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}

return buf || buff_to_string(rnds);
}

// Export public API
var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;

module.exports = uuid;
module.exports = v1;
29 changes: 29 additions & 0 deletions v4.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');

function v4(options, buf, offset) {
var i = buf && offset || 0;

if (typeof(options) == 'string') {
buf = options == 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};

var rnds = options.random || (options.rng || rng)();

// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;

// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}

return buf || bytesToUuid(rnds);
}

module.exports = v4;

0 comments on commit 681bddd

Please sign in to comment.