analytics icon indicating copy to clipboard operation
analytics copied to clipboard

Shrink UUID implementation

Open DavidWells opened this issue 4 years ago • 1 comments

Currently UUID is

function uuid() {
  var u = '',
  m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
  i = 0,
  rb = Math.random() * 0xffffffff|0;

  while (i++<36) {
    var c = m [i-1],
    r = rb&0xf,
    v = c=='x' ? r : (r&0x3|0x8);

    u += (c=='-' || c=='4') ? c : v.toString(16);
    rb = i%8==0 ? Math.random() * 0xffffffff|0 : rb>>4
  }
  return u
}

Should we shrink to

function uuid(a) {
  return a
    ? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
    : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
}

Crypto version

function uuid() {
    return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16));
}

Combined using crypto.getRandomValues with fallback

function uuid(a) {
  return a
    ? (a ^ ((crypto.getRandomValues ? crypto.getRandomValues(new Uint8Array(1))[0] : Math.random() * 16) & (15 >> a / 4))).toString(16)
    : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
}

Pros? Cons? ¯_(ツ)_/¯

DavidWells avatar Mar 11 '21 06:03 DavidWells

It's wonderfully tiny but I wonder if switching to a crypto based solution might be a more reliable method? I'm not sure what the targetted browsers are for this library but crypto is available in IE11+ and it's what the popular uuid library has now switched to (https://github.com/uuidjs/uuid/blob/master/src/rng-browser.js).

It's certainly quite a few more bytes than this implementation though but likely results in far fewer uuid collisions (particularly when bots are around with their dodgy Math.random() implementations).

paulboocock avatar Mar 11 '21 21:03 paulboocock