Browse Source

Add Global Unique Identifier

Signed-off-by: Sina Kuhestani <sina@ephpic.org>
Sina Kuhestani 1 day ago
parent
commit
03b381d6a7
1 changed files with 70 additions and 0 deletions
  1. 70 0
      src/GUID.php

+ 70 - 0
src/GUID.php

@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+namespace ePHPic\Utilities;
+
+/*******************************************************************************
+ * Class GUID
+ * *****************************************************************************
+ * This class provides utilities for generating globally unique identifiers
+ * (GUIDs) in the standard format (8-4-4-4-12). It ensures that each generated
+ * GUID is unique within the context of the application.
+ *
+ * @package   ePHPic\Utilities
+ * @author    Sina Kuhestani <sina@ephpic.org>
+ * @license   MIT License
+ * @copyright 2025 © Sina Kuhestani
+ * @link      https://code.ephpic.org/ephpic/utilities
+ ******************************************************************************/
+class GUID
+{
+    /**
+     * @var array<string> $ids Stores previously generated GUIDs to ensure
+     * uniqueness.
+     */
+    private static $ids = [];
+
+    /**
+     * Generates a GUID in the standard format (8-4-4-4-12).
+     *
+     * This method generates a random GUID using the version 4 UUID algorithm.
+     * It checks for uniqueness by comparing the newly generated GUID against
+     * previously generated GUIDs stored in the static $ids array. If a duplicate
+     * is found, the method recursively calls itself to generate a new GUID.
+     *
+     * @return string The generated GUID in the format
+     * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
+     *
+     * @throws \Exception If random bytes cannot be generated.
+     */
+    public static function generate(): string
+    {
+        /* Generate 16 random bytes */
+        $id = random_bytes(16);
+
+        /* Check if generated id is globally unique */
+        if (true === in_array($id, static::$ids))
+        { /* ❗ generated ID is not unique and MUST try to regerate the UUID */
+            return static::generate();
+        }
+
+        static::$ids[] = $id;
+
+        /* Set the version to 4 (randomly generated GUID) */
+        $id[6] = chr(ord($id[6]) & 0x0f | 0x40);
+
+        /* Set the variant to RFC 4122 */
+        $id[8] = chr(ord($id[8]) & 0x3f | 0x80);
+
+        /* Format the bytes into a GUID string */
+        return sprintf(
+            '%s-%s-%s-%s-%s',
+            bin2hex(substr($id, 0, 4)),
+            bin2hex(substr($id, 4, 2)),
+            bin2hex(substr($id, 6, 2)),
+            bin2hex(substr($id, 8, 2)),
+            bin2hex(substr($id, 10, 6))
+        );
+    }
+}