IDGenerator - PHP Online

Form of PHP Sandbox

Enter Your PHP code here for testing/debugging in the Online PHP Sandbox. As in the usual PHP files, you can also add HTML, but do not forget to add the tag <?php in the places where the PHP script should be executed.



Your result can be seen below.

Result of php executing





Full code of IDGenerator.php

  1. <?php
  2.  
  3. <?php
  4.  
  5. declare(strict_types=1);
  6.  
  7.  
  8. namespace Kyoto\Sandbox;
  9.  
  10. use InvalidArgumentException;
  11.  
  12. final class IDGenerator
  13. {
  14.     /**
  15.      * @var string[]
  16.      */
  17.     private array $alphabet = [
  18.         '0', '1', '2', '3', '4', '5', '6', '7', '8',
  19.         '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  20.         'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
  21.         'V', 'W', 'X', 'Y', 'Z'
  22.     ];
  23.  
  24.     /**
  25.      * @var string[]
  26.      */
  27.     private array $checksumAlphabet = [
  28.         '*', '$', '=', '@', '&', '%'
  29.     ];
  30.  
  31.     public function generate(string $bytes): string
  32.     {
  33.         $bin = gmp_strval(gmp_import($bytes), 2);
  34.         $bin = str_pad($bin, strlen($bytes) * 8, '0', STR_PAD_LEFT);
  35.         $bin = str_split($bin, 5);
  36.  
  37.         $last = array_pop($bin);
  38.         if (! is_null($last)) {
  39.             $bin[] = str_pad($last, 5, '0', STR_PAD_RIGHT);
  40.         }
  41.  
  42.         $encoded = implode(
  43.             '',
  44.             array_map(
  45.                 fn ($bits) => $this->getCharFromAlphabet(bindec($bits)),
  46.                 $bin
  47.             )
  48.         );
  49.         $checksum = $this->calculateChecksum($bytes);
  50.  
  51.         return $encoded . $this->getCharFromChecksumAlphabet($checksum);
  52.     }
  53.  
  54.     public function verify(string $id): bool
  55.     {
  56.         $calculatedChecksum = $this->calculateChecksum($this->decode($id));
  57.  
  58.         return $this->getCharFromChecksumAlphabet($calculatedChecksum) === $this->getChecksumCharFromId($id);
  59.     }
  60.  
  61.     public function decode(string $id): string
  62.     {
  63.         $normalizedId = $this->getIdWithoutChecksumChar($id);
  64.         $normalizedId = strtoupper($normalizedId);
  65.         $normalizedId = str_replace(['O', 'L', 'I', '-'], ['0', '1', '1', ''], $normalizedId);
  66.         $normalizedId = str_split($normalizedId);
  67.  
  68.         $bin = implode(
  69.             '',
  70.             array_map(
  71.                 fn ($char) => sprintf('%05b', array_search($char, $this->alphabet)),
  72.                 $normalizedId
  73.             )
  74.         );
  75.         $normalizedId = str_split($bin, 8);
  76.  
  77.         $last = array_pop($normalizedId);
  78.         if (! is_null($last) && strlen($last) === 8) {
  79.             $normalizedId[] = $last;
  80.         }
  81.  
  82.         return implode(
  83.             '',
  84.             array_map(
  85.                 fn ($bits) => chr(intval(bindec($bits))),
  86.                 $normalizedId
  87.             )
  88.         );
  89.     }
  90.  
  91.     private function calculateChecksum(string $bytes): int
  92.     {
  93.         $bigInt = gmp_strval(gmp_import($bytes));
  94.         $checksum = gmp_mod($bigInt, count($this->alphabet) + count($this->checksumAlphabet));
  95.  
  96.         return intval($checksum);
  97.     }
  98.  
  99.     private function getCharFromAlphabet(int $index): string
  100.     {
  101.         return $this->alphabet[$index] ?? throw new InvalidArgumentException(
  102.             'An array Index Out Of Bounds'
  103.         );
  104.     }
  105.  
  106.     private function getCharFromChecksumAlphabet(int $index): string
  107.     {
  108.         $mergedAlphabet = array_merge($this->alphabet, $this->checksumAlphabet);
  109.  
  110.         return $mergedAlphabet[$index] ?? throw new InvalidArgumentException(
  111.             'An array Index Out Of Bounds'
  112.         );
  113.     }
  114.  
  115.     private function getIdWithoutChecksumChar(string $id): string
  116.     {
  117.         return substr($id, 0, -1);
  118.     }
  119.  
  120.     private function getChecksumCharFromId(string $id): string
  121.     {
  122.         return substr($id, -1);
  123.     }
  124. }
File Description
  • IDGenerator
  • PHP Code
  • 15 Sep-2023
  • 3.22 Kb
You can Share it: