Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would one convert a UUID type to ULID type?

Theres a bit documentation out there how to convert ULID to UUID but not so much when you need to convert UUID to ULID.

I'm looking at this UUID / ULID generator / converter https://www.ulidtools.com/

but I'm not quite sure how I would replicate the UUID to ULID conversion, the source is too obfuscated for me to understand.

I'm not sure where to even begin, is this conversion even safe ? will it guarantee a unique conversion ?

like image 215
user3621898 Avatar asked Oct 19 '25 12:10

user3621898


2 Answers

I've had the same issue and I took a look at ulidtools.com then after digging into its source code for a while I found that it uses this package behind the seen.

import pkg from "id128";
const { Ulid, Uuid4 } = pkg;

const ulid = Ulid.generate();
const ulidToUuid = Uuid4.fromRaw(ulid.toRaw());
const uuidToUlid = Ulid.fromRaw(ulidToUuid.toRaw());

console.table([
  {
    generated_ulid: ulid.toCanonical(),
    converted_to_uuid: ulidToUuid.toCanonical(),
    converted_back_to_ulid: uuidToUlid.toCanonical(),
  },
]);

like image 150
Iman Hosseinipour Avatar answered Oct 21 '25 02:10

Iman Hosseinipour


Based on @ImanHosseiniPour answer I came up with the following:

TIMESTAMP + UUID = ULID

import { Ulid, Uuid4 } from "id128";
import { factory, decodeTime } from 'ulid'

const genUlid = factory();

function convertUuidToUlid(
  timestamp: Date, 
  canonicalUuid: string,
): Ulid {
  const uuid = Uuid4.fromCanonical(canonicalUuid);
  const convertedUlid = Ulid.fromRaw(uuid.toRaw())
  const ulidTimestamp = genUlid(timestamp.valueOf()).slice(0, 10)
  const ulidRandom = convertedUlid.toCanonical().slice(10);
  
  return Ulid.fromCanonical(ulidTimestamp + ulidRandom)
}

const timestamp = new Date()
const uuid = 'f0df59ea-bfe2-43a8-98d4-8213348daeb6'
const ulid = convertUuidToUlid(timestamp, uuid)
const originalUuid = Uuid4.fromRaw(ulid.toRaw());

console.table({
  timestamp: timestamp.valueOf(),
  uuid,
  ulid: ulid.toCanonical(),
  decodedTime: decodeTime(ulid.toCanonical()),
  originalUuid: originalUuid.toCanonical(),
});

Keep in mind that reverse engineering the ULID into a UUID will make the two first chunks different from the original since we incorporated the timestamp

like image 29
Renato Gama Avatar answered Oct 21 '25 03:10

Renato Gama