About
ObjectId are generated identifier (known as surrogate) with the intent to be unique for a Json.
ObjectId are custom UUID that are created from:
- a counter
- timestamp (milliseconds)
- node id (IP address or hostname)
- logical id (user, …)
- random integer
The risk of collisions is almost the same than for uuid.
The id is called ObjectId because Json is the string version of a Javascript Object
Implementation Example
MongoDb Object Id
They have been popularized by the MongoDb implementation.
They are:
- small (12 bytes in length)
- likely unique,
- fast to generate,
- and ordered values
consisting of:
- a 4-byte timestamp value, representing the ObjectId's creation, measured in seconds since the Unix epoch
- a 5-byte random value generated once per process. This random value is unique to the machine and process.
- a 3-byte incrementing counter, initialized to a random value
let mongoObjectId = function () {
let timestamp = (new Date().getTime() / 1000 | 0).toString(16);
return timestamp + 'xxxxxxxxxxxxxxxx'.replace(/[x]/g, function() {
return (Math.random() * 16 | 0).toString(16);
}).toLowerCase();
};
console.log("New Object Id: "+mongoObjectId());
Parse Server
This example has been adapted from the Parse Server Object Id implementation.
let randomBytes = function(n) {
let a = new Uint8Array(n), QUOTA = 65536;
for (let i = 0; i < n; i += QUOTA) {
crypto.getRandomValues(a.subarray(i, i + Math.min(n - i, QUOTA)));
}
return a;
};
let parseObjectId = function (size = 10) {
if (size === 0) {
throw new Error('Zero-length randomString is useless.');
}
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789';
let objectId = '';
const bytes = randomBytes(size);
for (let i = 0; i < bytes.length; ++i) {
let number = bytes[i]
objectId += chars[number % chars.length];
}
return objectId;
}
console.log("New Parse Object Id: "+parseObjectId());
Each of their IDs consists 1) of:
- 41 bits for time in milliseconds (41 years of IDs with a epoch and a latter custom start date)
- 13 bits that represent the logical shard ID (the node / computer / instance)
- 10 bits that represent an auto-incrementing sequence, modulus 1024. This means they can generate 1024 IDs, per shard, per millisecond