Cross-platform generation of UUID based on RFC-4122 .
Support for 1, 3, 4 and 5 versions of UUID. Port from node-uuid and using built-in Xorshift128+ for random generator.
Version 3 use Md5 for hash and version 5 use Sha1.
Generate and translate standard UUIDs into shorter - or just different - formats and back ( based on short-uuid ).
It also provides translators to convert back and forth from RFC compliant UUIDs to the shorter formats.
A tiny, secure, URL-friendly, unique string ID generator ( based on nanoid ).
- Small. 108 bytes (minified and gzipped). [Size Limit] controls the size.
- Fast. It is 40% faster than UUID.
- Safe. It uses Xorshift128+ RNG and can use any cryptographically strong RNG.
- Compact. It uses a larger alphabet than UUID (
A-Za-z0-9_-
). So ID size was reduced from 36 to 21 symbols. - Portable. Nano ID was ported to many programming languages.
FlakeId is a distributed ID generation algorithm based on Twitter Snowflake .
Advantages of FlakeID over UUID :
- Flake IDs are 64-bits, half the size of a UUID
- Can use time as first component and remain sortable
Each Flake ID is 64 bits long, consisting of:
- Timestamp - a 42 bit long number of milliseconds elapsed since 1 January 1970 00:00:00 UTC
- Datacenter Id - a 5 bit long datacenter identifier. It can take up to 32 unique values (including 0)
- Machine Id - a 5 bit long machine identifier. It can take up to 32 unique values (including 0)
- Counter - a 12 bit long counter of a self-increasing sequence. It can take up to 4096 unique values in a millisecond.
Breakdown of bits for an id e.g. 6848815309908238345
(counter is 9
, datacenter is 11
and worker 6
) is as follows:
010111110000101111100001001111001101111101 01011 00110 000000001001
|------------| 12 bit counter
|-----| 5 bit machine id
|-----| 5 bit datacenter id
|----- -----| 10 bit generator identifier
|------------------------------------------| 42 bit timestamp
Here is an example of usage, where we store nanoId in the database ( it's much more compact) , but it is shown to the user as uuid , for readability and security reasons.
var uniqueId = Uuid.nanoId(); // Generate unique id and store in database
var uuid = Uuid.fromNano(uniqueId); // Convert NanoId to Uuid and show on user screen
var searchUid = Uuid.toNano(uuid); // Server receive uuid and convert to NanoId. Use nanoId to search in database.
var shortUuid = Uuid.short();
var uuid = Uuid.fromShort(shortUuid);
Convert from any base to another base ( binary, hex, decimal, octal and many others) .
var vBinary = Uuid.convert("273247893827239437",Uuid.NUMBERS_DEC,Uuid.NUMBERS_BIN); //convert decimal to binary format
var vHex = Uuid.convert(vBinary, Uuid.NUMBERS_BIN, Uuid.NUMBERS_HEX); //convert bunary to hex format
var vBase58 = Uuid.convert(vHex, Uuid.NUMBERS_HEX, Uuid.FLICKR_BASE58); // convert hex to Base58 format
var vOctal = Uuid.convert(vBase58, Uuid.FLICKR_BASE58, Uuid.NUMBERS_OCT ); // convert from Base58 to octal format
For Uuid.v1() and Uuid.v4() you can pass any random function which return value between 0 and 255 . The default random generator is Xorshift128+ . Here is example for custom random function using Std.random
public function secureRandom():Int
{
return Std.random(256);
}
var uuid = Uuid.v1(secureRandom);
You can use Uuid to get any random number between some range, based on Xorshift128+ RNG, using the following code:
var dice:Int = Uuid.randomFromRange(1,6);
Uuid.nanoId() |
Create a tiny, secure, URL-friendly, unique string ID |
Uuid.short() |
Generate shorter UUIDs based on v4 |
Uuid.v1() |
Create a version 1 (timestamp) UUID |
Uuid.v3() |
Create a version 3 (namespace with MD5) UUID |
Uuid.v4() |
Create a version 4 (random) UUID |
Uuid.v5() |
Create a version 5 (namespace with SHA-1) UUID |
Uuid.NIL |
The nil UUID string (all zeros) |
Uuid.parse() |
Convert UUID string to bytes |
Uuid.stringify() |
Convert bytes to UUID string |
Uuid.randomFromRange() |
Return random number between range |
Uuid.randomByte() |
Return random value between 0 and 255 (included) |
Uuid.fromShort() |
Convert short uuid to Uuid based on the alphabet |
Uuid.toShort() |
Convert Uuid to short uuid based on the alphabet |
Uuid.fromNano() |
Convert nanoId to Uuid |
Uuid.toNano() |
Convert Uuid to nanoId |
Uuid.convert() |
Convert any string from one alphabet to another |
Uuid.validate() |
Test a string to see if it is a valid UUID |
Uuid.version() |
Detect RFC version of a UUID |
flakeId.nextId() |
Return generated id |
flakeId.setMachineId() |
Set unique machine id, default is random between 0 and 31 |
flakeId.setDatacenterId() |
Set unique datecenter id, default is random between 0 and 31 |
flakeId.setCustomEpoch() |
Set custom Epoch time , default is 1420070400 |
flakeId.timestamp() |
Get the current Unix time in milliseconds |
Uuid.DNS |
Returns the RFC 4122 identifier of the DNS namespace |
Uuid.URL |
Returns the RFC 4122 identifier of the URL namespace |
Uuid.ISO_OID |
Returns the RFC 4122 identifier of the ISO OID namespace |
Uuid.X500_DN |
Returns the RFC 4122 identifier of the X.500 namespace |
Uuid.LOWERCASE_BASE26 |
Lowercase English letters |
Uuid.UPPERCASE_BASE26 |
Uppercase English letters. |
Uuid.NO_LOOK_ALIKES_BASE51 |
Numbers and english alphabet without lookalikes: 1 , l , I , 0 , O , o , u , v , 5 , S , s |
Uuid.FLICKR_BASE58 |
Avoid similar characters 0/O, 1/I/l |
Uuid.BASE_70 |
Numbers, English letters and special character |
Uuid.BASE_85 |
Numbers, English letters and special character (ZeroMQ (Z85) alphabet) |
Uuid.COOKIE_BASE90 |
Safe for HTTP cookies values |
Uuid.NANO_ID_ALPHABET |
Alphabet used to create NanoId string |
Uuid.NUMBERS_BIN |
Binary numbers |
Uuid.NUMBERS_OCT |
Octal numbers |
Uuid.NUMBERS_DEC |
Decimal numbers |
Uuid.NUMBERS_HEX |
Hex numbers |
Create unique string ID
NanoId is 40% faster than UUID and uses a larger alphabet than UUID (A-Za-z0-9_-), so default size is reduced from 36 to 21 symbols. It is comparable to UUID v4.
len |
Int Size of the NanoId string ( default is 21 ) |
alphabet |
String Alphabet used to generate NanoId |
randomFunc |
Void->Int Any random function that returns a random bytes (0-255) |
returns | String |
Example:
trace("Uuid: "+Uuid.nanoId()); // 6OxUkLI4bGmR_JlVMX9fQ
Create shorter version for UUID based UUID v4.
toAlphabet |
String Alphabet used to generate short-uuid |
randomFunc |
Void->Int Any random function that returns a random bytes (0-255) |
returns | String |
Example:
trace("Uuid: "+Uuid.short()); // mhvXdrZT4jP5T8vBxuvm75
The nil UUID string (all zeros).
Example:
trace("Uuid:" +Uuid.NIL); // ⇨ '00000000-0000-0000-0000-000000000000'
Convert UUID string to Bytes
uuid |
String A valid UUID |
separator |
String Set different divider ( default is - ) |
returns | Bytes |
Example:
// Parse a UUID
var b = Uuid.parse('6ae99955-2a0d-5dca-94d6-2e2bc8b764d3');
trace("Hex: "+b.toHex()); // 6ae999552a0d5dca94d62e2bc8b764d3
// Hex representation on the byte order (for documentation purposes)
// [
// '6a', 'e9', '99', '55',
// '2a', '0d', '5d', 'ca',
// '94', 'd6', '2e', '2b',
// 'c8', 'b7', '64', 'd3'
// ]
Convert Bytes to UUID string using separator
data |
Bytes Should be 16 bytes |
separator |
String Set different divider ( default is - ) |
returns | String |
Example:
var b = Bytes.ofHex("6ae999552a0d5dca94d62e2bc8b764d3");
trace("Uuid: "+Uuid.stringify(b)); //6ae99955-2a0d-5dca-94d6-2e2bc8b764d3
Test a string to see if it is a valid UUID
uuid |
String to validate |
separator |
String Set different divider ( default is - ) |
returns | true if string is a valid UUID, false otherwise |
Example:
Uuid.validate('not a UUID'); // ⇨ false
Uuid.validate('6ae99955-2a0d-5dca-94d6-2e2bc8b764d3'); // ⇨ true
Detect RFC version of a UUID
uuid |
String A valid UUID |
separator |
String Set different divider ( default is - ) |
returns | Int The RFC version of the UUID |
Example:
Uuid.version('45637ec4-c85f-11ea-87d0-0242ac130003'); // ⇨ 1
Uuid.version('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'); // ⇨ 4
Return random number between min and max (included) values
min |
Int Start number |
max |
Int End number |
returns | Int |
Example:
Uuid.randomFromRange(1,6); // return a number in range [1,6]
Return a random number between 0 and 255 (included)
returns | Int |
Example:
Uuid.randomByte(); // return a number in range [0,255]
Translate shorter UUID format to standard UUID
shortUuid |
String short uuid string |
separator |
String Set divider ( default is - ) |
fromAlphabet |
String Alphabet to use for translation ( default FLICKR_BASE58 ) |
returns | String |
COOKIE_BASE90
, FLICKR_BASE58
, BASE_70
, BASE_85
, LOWERCASE_BASE26
, UPPERCASE_BASE26
, NO_LOOK_ALIKES_BASE51
, NUMBERS_BIN
, NUMBERS_OCT
, NUMBERS_DEC
, NUMBERS_HEX
Example:
Uuid.fromShort("ecHyJhpvZANyZY6k1L5EYK"); // 6ae99955-2a0d-5dca-94d6-2e2bc8b764d3
Translate standard UUIDs into shorter format
uuid |
String A valid UUID |
separator |
String Set divider ( default is - ) |
toAlphabet |
String Alphabet to use for translation ( default FLICKR_BASE58 ) |
returns | String |
COOKIE_BASE90
, FLICKR_BASE58
, BASE_70
, BASE_85
, LOWERCASE_BASE26
, UPPERCASE_BASE26
, NO_LOOK_ALIKES_BASE51
, NUMBERS_BIN
, NUMBERS_OCT
, NUMBERS_DEC
, NUMBERS_HEX
Example:
Uuid.toShort('6ae99955-2a0d-5dca-94d6-2e2bc8b764d3'); // ecHyJhpvZANyZY6k1L5EYK
Translate shorter UUID format to standard UUID
nanoUuid |
String A valid nanoId string |
separator |
String Set divider ( default is - ) |
fromAlphabet |
String Alphabet to use for translation ( default FLICKR_BASE58 ) |
returns | String |
COOKIE_BASE90
, FLICKR_BASE58
, BASE_70
, BASE_85
, LOWERCASE_BASE26
, UPPERCASE_BASE26
, NO_LOOK_ALIKES_BASE51
, NUMBERS_BIN
, NUMBERS_OCT
, NUMBERS_DEC
, NUMBERS_HEX
Example:
Uuid.fromShort("ecHyJhpvZANyZY6k1L5EYK"); // 6ae99955-2a0d-5dca-94d6-2e2bc8b764d3
Translate standard UUIDs into shorter format
uuid |
String A valid UUID |
separator |
String Set divider ( default is - ) |
toAlphabet |
String Alphabet to use for translation ( default FLICKR_BASE58 ) |
returns | String |
COOKIE_BASE90
, FLICKR_BASE58
, BASE_70
, BASE_85
, LOWERCASE_BASE26
, UPPERCASE_BASE26
, NO_LOOK_ALIKES_BASE51
, NUMBERS_BIN
, NUMBERS_OCT
, NUMBERS_DEC
, NUMBERS_HEX
Example:
Uuid.toShort('6ae99955-2a0d-5dca-94d6-2e2bc8b764d3'); // ecHyJhpvZANyZY6k1L5EYK
Convert any string from one alphabet to another
number |
String Any number or string |
fromAlphabet |
String Alphabet source ( for number ) |
toAlphabet |
String Alphabet destination |
returns | String |
Example:
Uuid.convert('12345',Uuid.NUMBERS_DEC,Uuid.NUMBERS_BIN); // 11000000111001
Uuid.convert('12345678',Uuid.NUMBERS_DEC,Uuid.NUMBERS_HEX); // ⇨ bc614e
Uuid.convert('1234567890',Uuid.NUMBERS_DEC,Uuid.BASE_70); // ⇨ PtmIa
Uuid.v1(node, optClockSequence, msecs, optNsecs, randomFunc, separator, shortUuid, toAlphabet):String
Create an RFC version 1 (timestamp) UUID
node |
Bytes RFC "node" field as 6 bytes |
optClockSequence |
RFC "clock sequence" as a Int between 0 - 0x3fff |
msecs |
RFC "timestamp" field (Float of milliseconds, unix epoch) |
optNsecs |
RFC "timestamp" field (Int of nanseconds to add to msecs , should be 0-10,000) |
randomFunc |
Void->Int Any random function that returns a random bytes (0-255) |
separator |
String Set divider ( default is - ) |
shortUuid |
Bool If true UUID will be exported as short UUID |
toAlphabet |
String Alphabet used for export on short UUID |
returns | UUID String |
throws | Error if more than 10M UUIDs/sec are requested |
Example:
Uuid.v1(); // ⇨ '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d'
Example using with options:
var node = Bytes.ofHex("010207090506");
var optClockSequence = 0x1a7f;
var msecs = 1556526368;
var optNsecs = 6200;
uuid = Uuid.v1(node,optClockSequence,msecs,optNsecs); // ⇨ '25848a38-1cd0-11b2-9a7f-010207090506'
Create an RFC version 3 (namespace w/ MD5) UUID
API is identical to v5()
, but uses "v3" instead.
Create an RFC version 4 (random) UUID
randBytes |
Bytes 16 random bytes (0-255) |
randomFunc |
Void->Int Any random function that returns a random bytes (0-255) |
separator |
String Set divider ( default is - ) |
shortUuid |
Bool If true UUID will be exported as short UUID |
toAlphabet |
String Alphabet used for export on short UUID |
returns | UUID String |
Example:
Uuid.v4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'
Example using predefined random
values:
var randomValues= Bytes.ofHex("109156bec4fbc1ea71b4efe1671c5836");
Uuid.v4(randomValues); // ⇨ '109156be-c4fb-41ea-b1b4-efe1671c5836'
Create an RFC version 5 (namespace w/ SHA-1) UUID
name |
String |
namespace |
String Namespace UUID |
separator |
String Set divider ( default is - ) |
shortUuid |
Bool If true UUID will be exported as short UUID |
toAlphabet |
String Alphabet used for export on short UUID |
returns | UUID String if no buffer is specified, otherwise returns buffer |
Note: The RFC DNS
and URL
namespaces are available as Uuid.DNS
and Uuid.URL
.
Example with custom namespace:
// Define a custom namespace. Readers, create your own using something like
// https://www.uuidgenerator.net/
var MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';
Uuid.v5('Hello, World!', MY_NAMESPACE); // ⇨ '630eb68f-e0fa-5ecc-887a-7c7a62614681'
Example with RFC URL
namespace:
Uuid.v5('https://www.w3.org/', Uuid.URL); // ⇨ 'c106a26a-21bb-5538-8bf2-57095d1976c1'
Return a unique 64-bit number
returns | Int64 |
Example:
var flakeId = new FlakeId();
flakeId.nextId(); // return a unique identifier
Set machine identifier ( could be 0 to 31)
machineId |
Int A 5 bit long machine identifier |
returns |
Example:
var flakeId = new FlakeId();
flakeId.setMachineId(4);
Set machine identifier ( could be 0 to 31)
datacenterId |
Int A 5 bit long datacenter identifier |
returns |
Example:
var flakeId = new FlakeId();
flakeId.setDatacenterId(9);
Set time in milliseconds elapsed since 1 January 1970 00:00:00 UTC
customEpoch |
Int64 Unix time in milliseconds |
returns |
Example:
var flakeId = new FlakeId();
flakeId.setCustomEpoch(Int64.make(0x0000015F,0x2064AA48));
Return the current Unix time in milliseconds
returns | Int64 |
Example:
var flakeId = new FlakeId();
flakeId.timestamp(); //Current time in milliseconds
Version 1 (timestamp):
var uuid = Uuid.v1();
trace("UUID: " + uuid);
// Using custom separator
var uuid = Uuid.v1("_");
trace("UUID: " + uuid);
//Using predefined values
var node = Bytes.ofHex("010203040506"); // Array of 6 bytes, by default is random generated
var optClockSequence = 0x1a7f; // clock sequence (0 - 0x3fff)
var msecs = 1556526368; // Time in milliseconds since unix Epoch
var optNsecs = 4500; // Additional time in nanoseconds (0-9999)
uuid = Uuid.v1(node,optClockSequence,msecs,optNsecs);
trace("UUID: " + uuid);
Version 3 (namespace):
var uuid = Uuid.v3("https://example.com/haxe",Uuid.URL); //namespace should be valid Uuid
trace("UUID: " + uuid);
uuid = Uuid.v3("The Cross-platform Toolkit");
trace("UUID: " + uuid);
uuid = Uuid.v3("The Cross-platform Toolkit",'7e9606ce-8af4-435b-89d6-66d6d885b97a');
trace("UUID: " + uuid);
Version 4 (random):
var uuid = Uuid.v4();
trace("UUID: " + uuid);
//Using custom separator - empty position
var uuid = Uuid.v4("");
trace("UUID: " + uuid);
Version 5 (namespace):
var uuid = Uuid.v5("https://example.com/haxe",Uuid.URL);
trace("UUID: " + uuid);
uuid = Uuid.v5("The Cross-platform Toolkit");
trace("UUID: " + uuid);
uuid = Uuid.v5("The Cross-platform Toolkit",'7e9606ce-8af4-435b-89d6-66d6d885b97a');
trace("UUID: " + uuid);
Flake ID
var flakeId = new FlakeId(11,6); // datecenterid is `11` and machineid id `6`
var uniqueId = flakeId.nextId(); // create one unique id
for (i in 0...10) {
trace(flakeId.nextId()); //generate ten unique ids
}