Source of file IDGenerator.php

Size: 2,756 Bytes - Last Modified: 2021-01-12T22:04:13+00:00

C:/Users/MAKS/Code/_PROJECTS/amqp-agent/src/Helper/IDGenerator.php

123456789101112131415161718192021222324252627
Covered by 4 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashWithAditionalParametersGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testRequestMethodViaAliasMethodCall
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testAnExceptionIsRaisedIfCorrelationIdOfTheResponseIsNotTheSameAsTheRequest
28
Covered by 4 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashWithAditionalParametersGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testRequestMethodViaAliasMethodCall
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testAnExceptionIsRaisedIfCorrelationIdOfTheResponseIsNotTheSameAsTheRequest
2930
Covered by 4 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateHashWithAditionalParametersGeneratesUniqueHashes
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testRequestMethodViaAliasMethodCall
  • MAKS\AmqpAgent\Tests\RPC\ClientEndpointTest::testAnExceptionIsRaisedIfCorrelationIdOfTheResponseIsNotTheSameAsTheRequest
313233343536373839404142
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
43
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
44
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
45
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
46
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
4748
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
4950
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
5152
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
53545556
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
5758596061626364656667
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
68
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
69
Covered by 1 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
707172
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
73
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
74
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
75
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
767778
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
79
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
80
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
81
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
82
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
83
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
8485
Covered by 2 test(s):
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenGeneratesUniqueTokens
  • MAKS\AmqpAgent\Tests\Helper\IDGeneratorTest::testGenerateTokenWithAditionalParametersGeneratesUniqueTokens
868788
<?php

/**
 * @author Marwan Al-Soltany <MarwanAlsoltany@gmail.com>
 * @copyright Marwan Al-Soltany 2020
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

declare(strict_types=1);

namespace MAKS\AmqpAgent\Helper;

/**
 * A class containing functions for generating unique IDs and Tokens.
 * @since 2.0.0
 */
final class IDGenerator
{
    /**
     * Generates an md5 hash from microtime and uniqid.
     * @param string $entropy [optional] Additional entropy.
     * @return string
     */
    public static function generateHash(string $entropy = 'maks-amqp-agent-id'): string
    {
        $prefix = sprintf('-%s-[%d]-', $entropy, rand());
        $symbol = microtime(true) . uniqid($prefix, true);

        return md5($symbol);
    }

    /**
     * Generates a crypto safe unique token. Note that this function is pretty expensive.
     * @param int $length The length of the token. If the token is hashed this will not be the length of the returned string.
     * @param string|null $charset [optional] A string of characters to generate the token from. Defaults to alphanumeric.
     * @param string|null $hashing [optional] A name of hashing algorithm to hash the generated token with. Defaults to no hashing.
     * @return string
     */
    public static function generateToken(int $length = 32, ?string $charset = null, ?string $hashing = null): string
    {
        $token = '';
        $charset = $charset ?? (
            implode(range('A', 'Z')) .
            implode(range('a', 'z')) .
            implode(range(0, 9))
        );
        $max = strlen($charset);

        for ($i = 0; $i < $length; $i++) {
            $token .= $charset[
                self::generateCryptoSecureRandom(0, $max - 1)
            ];
        }

        return $hashing ? hash($hashing, $token) : $token;
    }

    /**
     * Generates a crypto secure random number.
     * @param int $min
     * @param int $max
     * @return int
     */
    protected static function generateCryptoSecureRandom(int $min, int $max): int
    {
        $range = $max - $min;
        if ($range < 1) {
            return $min;
        }

        $log = ceil(log($range, 2));
        $bytes = (int)(($log / 8) + 1); // length in bytes
        $bits = (int)($log + 1); // length in bits
        $filter = (int)((1 << $bits) - 1); // set all lower bits to 1

        do {
            $random = PHP_VERSION >= 7
                ? random_bytes($bytes)
                : openssl_random_pseudo_bytes($bytes);
            $random = hexdec(bin2hex($random));
            $random = $random & $filter; // discard irrelevant bits
        } while ($random > $range);

        return $min + $random;
    }
}