File: PeclUuidNameGeneratorTest.php

package info (click to toggle)
php-ramsey-uuid 4.7.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,124 kB
  • sloc: php: 13,359; xml: 194; python: 54; makefile: 16
file content (105 lines) | stat: -rw-r--r-- 3,463 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php

declare(strict_types=1);

namespace Ramsey\Uuid\Test\Generator;

use Ramsey\Uuid\BinaryUtils;
use Ramsey\Uuid\Exception\NameException;
use Ramsey\Uuid\Generator\PeclUuidNameGenerator;
use Ramsey\Uuid\Test\TestCase;
use Ramsey\Uuid\Uuid;

use function hash;
use function pack;
use function substr;
use function substr_replace;
use function unpack;

class PeclUuidNameGeneratorTest extends TestCase
{
    /**
     * @param non-empty-string $ns
     *
     * @dataProvider provideNamesForHashingTest
     * @requires extension uuid
     */
    public function testPeclUuidNameGeneratorHashesName(string $ns, string $name, string $algorithm): void
    {
        $namespace = Uuid::fromString($ns);
        $version = $algorithm === 'md5' ? 3 : 5;
        $expectedBytes = substr(hash($algorithm, $namespace->getBytes() . $name, true), 0, 16);

        // Need to add the version and variant, since ext-uuid already includes
        // these in the values returned.
        /** @var array $unpackedTime */
        $unpackedTime = unpack('n*', substr($expectedBytes, 6, 2));
        $timeHi = (int) $unpackedTime[1];
        $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version));

        /** @var array $unpackedClockSeq */
        $unpackedClockSeq = unpack('n*', substr($expectedBytes, 8, 2));
        $clockSeqHi = (int) $unpackedClockSeq[1];
        $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi));

        $expectedBytes = substr_replace($expectedBytes, $timeHiAndVersion, 6, 2);
        $expectedBytes = substr_replace($expectedBytes, $clockSeqHiAndReserved, 8, 2);

        $generator = new PeclUuidNameGenerator();
        $generatedBytes = $generator->generate($namespace, $name, $algorithm);

        $this->assertSame(
            $expectedBytes,
            $generatedBytes,
            'Expected: ' . bin2hex($expectedBytes) . '; Received: ' . bin2hex($generatedBytes)
        );
    }

    /**
     * @return array<array{ns: string, name: string, algorithm: string}>
     */
    public function provideNamesForHashingTest(): array
    {
        return [
            [
                'ns' => Uuid::NAMESPACE_URL,
                'name' => 'https://example.com/foobar',
                'algorithm' => 'md5',
            ],
            [
                'ns' => Uuid::NAMESPACE_URL,
                'name' => 'https://example.com/foobar',
                'algorithm' => 'sha1',
            ],
            [
                'ns' => Uuid::NAMESPACE_OID,
                'name' => '1.3.6.1.4.1.343',
                'algorithm' => 'sha1',
            ],
            [
                'ns' => Uuid::NAMESPACE_OID,
                'name' => '1.3.6.1.4.1.52627',
                'algorithm' => 'md5',
            ],
            [
                'ns' => 'd988ae29-674e-48e7-b93c-2825e2a96fbe',
                'name' => 'foobar',
                'algorithm' => 'sha1',
            ],
        ];
    }

    public function testGenerateThrowsException(): void
    {
        $namespace = Uuid::fromString('cd998804-c661-4264-822c-00cada75a87b');
        $generator = new PeclUuidNameGenerator();

        $this->expectException(NameException::class);
        $this->expectExceptionMessage(
            'Unable to hash namespace and name with algorithm \'aBadAlgorithm\''
        );

        /** @phpstan-ignore-next-line */
        $generator->generate($namespace, 'a test name', 'aBadAlgorithm');
    }
}