Generate CUIDs in PHP

Resources  |  Generate CUIDs in PHP

Generating a CUID (Collision-resistant Unique Identifier) in PHP involves using various techniques to ensure uniqueness, such as the current timestamp, a counter, a machine fingerprint, and randomness. Below is an example implementation of generating a CUID in PHP.

Steps to Generate a CUID in PHP

  1. Timestamp: Get the current timestamp in milliseconds.
  2. Counter: Use a counter to handle multiple CUIDs generated in a short period.
  3. Fingerprint: Generate a machine-specific fingerprint.
  4. Randomness: Add random characters to further reduce the risk of collisions.
  5. Base36 Encoding: Encode the components using Base36 for readability.

Example Code

<?php

class CUIDGenerator {
    private static $counter = 0;
    private static $lastTimestamp = 0;

    private static function encodeBase36($value) {
        $base36Chars = '0123456789abcdefghijklmnopqrstuvwxyz';
        $result = '';
        while ($value > 0) {
            $result = $base36Chars[$value % 36] . $result;
            $value = (int)($value / 36);
        }
        return str_pad($result, 8, '0', STR_PAD_LEFT);
    }

    private static function getMachineFingerprint() {
        $hostname = gethostname();
        $hash = md5($hostname);
        return substr($hash, 0, 4);
    }

    private static function getRandomString($length) {
        $base36Chars = '0123456789abcdefghijklmnopqrstuvwxyz';
        $result = '';
        for ($i = 0; $i < $length; $i++) {
            $result .= $base36Chars[random_int(0, 35)];
        }
        return $result;
    }

    public static function generateCUID() {
        $timestamp = intval(microtime(true) * 1000);

        if ($timestamp == self::$lastTimestamp) {
            self::$counter++;
        } else {
            self::$lastTimestamp = $timestamp;
            self::$counter = 0;
        }

        $timestampBase36 = self::encodeBase36($timestamp);
        $counterBase36 = self::encodeBase36(self::$counter);
        $fingerprint = self::getMachineFingerprint();
        $randomString = self::getRandomString(4);

        return "c$timestampBase36$counterBase36$fingerprint$randomString";
    }
}

// Example usage
echo CUIDGenerator::generateCUID();

?>

Explanation

  1. Base36 Encoding:

    • The encodeBase36 function converts a number to a Base36 encoded string, padded to ensure a consistent length.
  2. Timestamp:

    • intval(microtime(true) * 1000) gets the current timestamp in milliseconds.
  3. Counter:

    • A static counter is used to handle multiple CUIDs generated within the same millisecond. The counter is incremented and reset as needed.
  4. Machine Fingerprint:

    • getMachineFingerprint generates a fingerprint using the MD5 hash of the machine's hostname.
  5. Random String:

    • getRandomString generates a random string of specified length using Base36 characters.
  6. Combine Components:

    • The generateCUID method combines the timestamp, counter, fingerprint, and random parts to form the final CUID.

Summary

This PHP implementation of CUID generation uses available functions and libraries to handle timestamps, hashing, randomness, and counters. This approach ensures that the generated CUIDs are unique, readable, and collision-resistant, making them suitable for various applications.