GithubHelp home page GithubHelp logo

jchook / uuid-random Goto Github PK

View Code? Open in Web Editor NEW
104.0 5.0 23.0 63 KB

Tiny, fast UUID v4 with cryptographic PRNG

License: MIT License

JavaScript 68.93% HTML 31.07%
uuid ids distributed-systems random-uuids rng

uuid-random's Introduction

uuid-random

MIT Licence Stable

Generate RFC-4122 compliant random UUIDs (version 4) with better statistical dispersion than Math.random().

Install

npm i uuid-random

Or download the latest release.

Features

Compatibility

Compatible with almost all versions of:

  • Node
  • Babel
  • TypeScript
  • Web browsers

Performance

The included benchmark.js as well as independent benchmarks rank this library as the fastest pure JS UUID v4 generator available with cryptographically secure PRNG— almost 20x faster than the most popular library (using latest NodeJS).

npm package performance
portable-uuid 354k ops/sec
uuid 474k ops/sec
id128 6.0M ops/sec
uuid-random (this) 9.7M ops/sec

Results above generated on a 4.20GHz Intel i7-7700K with Node v12.18.0

Why use UUID?

Universally Unique IDentifiers transcend many constraints of traditional incremental integer IDs, especially in distributed systems. In UUID version 4, we essentially generate a random 128-bit value.

We do trade guaranteed uniqueness for extremely probable uniqueness (you would need to do-loop uuid() at max speed for 73,067 years for a 50% chance of one collision). But for that slight cost, we may now generate valid, unique, persistent IDs on any node of a distributed system (e.g. intermittently offline or high-latency clients).

Note, if you plan to use UUIDs for a new project, depending on your requirements, you may consider a more recent standard that addresses some of the shortcomings of UUID, such as flake-id, nanoid, cuid, or ulid.

Example Usage

Babel

import uuid from 'uuid-random';
uuid(); // 'f32dc9ae-7ca8-44ca-8f25-f258f7331c55'

Node

var uuid = require('uuid-random');
uuid(); // '0b99b82f-62cf-4275-88b3-de039020f14e'

Browser

<script src="uuid-random.min.js"></script>
<script>
  uuid(); // 'b96ab5e6-f1e8-4653-ab08-4dd82ea65778'
</script>

Validate a UUID v4 String

uuid.test('0b99b82f-62cf-4275-88b3-de039020f14e'); // true

Generate Binary UUIDs

uuid.bin(); // <Buffer 41 db 10 54 b3 61 48 50 87 f1 2f 7b 08 a5 0f 06>

Contributing

Feel free to open an issue or submit a pull request.

License

MIT.

uuid-random's People

Contributors

aarondcohen avatar alixaxel avatar dlongley avatar federicobiccheddu avatar henriqueqc avatar jchook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

uuid-random's Issues

Reuse pool more times

This is good work.

Currently with the bufIdx += n the uuid.BUFFER_SIZE pool of random bytes gets exhausted after uuid.BUFFER_SIZE / n times (e.g. 512 / 16), which is not much.

In practice, this can be just bufIdx ++ and pool gets used uuid.BUFFER_SIZE - n times (e.g. 512 - 16)

There is no effect on uniqueness, since unless all the n + 1 bytes are equal in value, bufIdx ++ is as random as bufIdx += n

This improves the mileage.

Something like buf.slice(bufIdx, bufIdx + n), modifying the condition to be (++bufIdx + n) > uuid.BUFFER_SIZE)

Would you consider adding an export for the empty UUID?

When I work with UUIDs I find I often need to use the empty UUID (00000000-0000-0000-0000-000000000000) at times, and as I was using this library for generating my UUIDs I thought it would be nice to have it include the empty UUID as an export so I don't have to define it in my own code.

The API would be something like:

const uuid = require('uuid-random');
const myEmpty = uuid.empty;

Would you consider a PR of this sort are you not interested?

RFC Compliancy

As per the RFC:

The algorithm is as follows:

   o  Set the two most significant bits (bits 6 and 7) of the
      clock_seq_hi_and_reserved to zero and one, respectively.

   o  Set the four most significant bits (bits 12 through 15) of the
      time_hi_and_version field to the 4-bit version number from
      Section 4.1.3.

   o  Set all the other bits to randomly (or pseudo-randomly) chosen
      values.
   See Section 4.5 for a discussion on random numbers.

uuidbin() has b[8] = (b[8] & 0x3f) | 0x80; but this doesn't correspond to #1, where bits 6 and 7 should be zero and one. Example: getRandomInt(0, 255) can return 200. Assuming (200 & 0x3f) | 0x80 we get 136, which is 10001000 in binary, where you can see bits 6 and 7 are not zero and one. they're both zero.

iOS 9 Bug

See #14

iOS 9 somehow doesn't have Uint8Array.prototype.slice, despite caniuse saying that it does.

Conversion methods

Can you add simple conversion methods for uuid.toString() and uuid.toBin() to module? Because sometimes both formats needed with same value.

uuid.test() for uppercased UUID returns false

const id = uuid();
console.log(uuid.test(id)); // true
console.log(uuid.test(id.toUpperCase())); // false

I think treating uppercased hexadecimals as invalid aren't right. test() function's regexp should be case-insensitive.

Doesn't work.

import uuid from 'uuid-random';
uuid();

Generates c7ffe9d4-60bb-4a1d-bf8c-994749883c72 every. single. time. On any browser or device. Same webpage.

Node 12.14.1
npm 6.13.4
React 16.10.2
Babel 7.0.0
Webpack 3.8.1

remove if the if condition by assigning function statically

The crypto availability is being checked every time randomBytes method is called here

This if else condition checking can be done just once at the beginning, and assign the correct function to a variable, something like below:

const randomBytes = (typeof crypto !== 'undefined') ? randomCrypto : randomMath;

let bufIdx = uuid.BUFFER_SIZE;
function randomCrypto(n) {
      if ((++bufIdx + n) > uuid.BUFFER_SIZE) {
        bufIdx = 0;
        if (crypto.getRandomValues) {
          buf = new Uint8Array(uuid.BUFFER_SIZE);
          crypto.getRandomValues(bytes);
        } else if (crypto.randomBytes) {
          buf = crypto.randomBytes(uuid.BUFFER_SIZE);
        } else {
          throw new Error('Non-standard crypto library');
        }
      }
      return buf.slice(bufIdx, bufIdx + n);
}
function randomMath(n) { 
      r = [];
      for (i = 0; i < n; i++) {
        r.push(getRandomInt(0, 255));
      }
      return r;
}

This further improves the performance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.