UNPKG

sodium-uuid

Version:

Generate v4 UUIDs using libsodium's RNG

69 lines (51 loc) 1.83 kB
'use strict' var sodium = require('sodium-native') var assert = require('assert') var BYTES = 16 module.exports = create function create (buf) { assert(buf == null ? true : Buffer.isBuffer(buf), 'buf must be Buffer') assert(buf == null ? true : buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes') if (buf == null) { buf = Buffer.allocUnsafe(BYTES) } sodium.randombytes_buf(buf.slice(0, BYTES)) // Mask then set bits // https://tools.ietf.org/html/rfc4122#section-4.1.2 // time_hi_and_version (MSB half) // IETF variant buf[6] = (buf[6] & 0b00001111) | 0b01000000 // clock_seq_hi_and_reserved // version buf[8] = (buf[8] & 0b00111111) | 0b10000000 return buf } var REGEX = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[ab89][a-f0-9]{3}-[a-f0-9]{12}$/i create.isUUID = function (uuid) { if (typeof uuid === 'string') return uuid.length === 36 && REGEX.test(uuid) assert(Buffer.isBuffer(uuid), 'uuid must be string or Buffer') return uuid.byteLength >= BYTES && (uuid[6] & 0b11110000) === 0b01000000 && (uuid[8] & 0b11000000) === 0b10000000 } create.stringify = function (buf) { assert(Buffer.isBuffer(buf), 'buf must be Buffer') assert(buf.byteLength >= BYTES, 'buf must be at least BYTES (' + BYTES + ') bytes') assert(create.isUUID(buf), 'Could not parse buf (' + buf + '): Invalid UUIDv4') return [ buf.slice(0, 4), buf.slice(4, 6), buf.slice(6, 8), buf.slice(8, 10), buf.slice(10, 16) ].map(function (subbuf) { return subbuf.toString('hex') }).join('-') } create.parse = function (str, buf) { if (buf == null) buf = Buffer.allocUnsafe(BYTES) buf.write(str.replace(/-/g, ''), 0, BYTES, 'hex') assert(create.isUUID(buf), 'Could not parse str (' + str + '): Invalid UUIDv4') return buf } create.BYTES = BYTES