Skip to content

Commit

Permalink
Added the UUID extension to Core and deprecated the global uuid call …
Browse files Browse the repository at this point in the history
…with an uuid3 to specify version (FakerPHP#427)
  • Loading branch information
pimjansen authored and krsriq committed Jan 23, 2022
1 parent 51f6498 commit 0e8aec4
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/Faker/Core/Uuid.php
@@ -0,0 +1,56 @@
<?php

namespace Faker\Core;

use Faker\Extension\UuidExtension;

final class Uuid implements UuidExtension
{
public function uuid3(): string
{
$number = new Number();

// fix for compatibility with 32bit architecture; each mt_rand call is restricted to 32bit
// two such calls will cause 64bits of randomness regardless of architecture
$seed = $number->numberBetween(0, 2147483647) . '#' . $number->numberBetween(0, 2147483647);

// Hash the seed and convert to a byte array
$val = md5($seed, true);
$byte = array_values(unpack('C16', $val));

// extract fields from byte array
$tLo = ($byte[0] << 24) | ($byte[1] << 16) | ($byte[2] << 8) | $byte[3];
$tMi = ($byte[4] << 8) | $byte[5];
$tHi = ($byte[6] << 8) | $byte[7];
$csLo = $byte[9];
$csHi = $byte[8] & 0x3f | (1 << 7);

// correct byte order for big edian architecture
if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
$tLo = (($tLo & 0x000000ff) << 24) | (($tLo & 0x0000ff00) << 8)
| (($tLo & 0x00ff0000) >> 8) | (($tLo & 0xff000000) >> 24);
$tMi = (($tMi & 0x00ff) << 8) | (($tMi & 0xff00) >> 8);
$tHi = (($tHi & 0x00ff) << 8) | (($tHi & 0xff00) >> 8);
}

// apply version number
$tHi &= 0x0fff;
$tHi |= (3 << 12);

// cast to string
return sprintf(
'%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
$tLo,
$tMi,
$tHi,
$csHi,
$csLo,
$byte[10],
$byte[11],
$byte[12],
$byte[13],
$byte[14],
$byte[15]
);
}
}
1 change: 1 addition & 0 deletions src/Faker/Extension/ContainerBuilder.php
Expand Up @@ -66,6 +66,7 @@ public static function defaultExtensions(): array
FileExtension::class => Core\File::class,
NumberExtension::class => Core\Number::class,
VersionExtension::class => Core\Version::class,
UuidExtension::class => Core\Uuid::class,
];
}

Expand Down
16 changes: 16 additions & 0 deletions src/Faker/Extension/UuidExtension.php
@@ -0,0 +1,16 @@
<?php

namespace Faker\Extension;

/**
* @experimental This interface is experimental and does not fall under our BC promise
*/
interface UuidExtension extends Extension
{
/**
* Generate name based md5 UUID (version 3).
*
* @example '7e57d004-2b97-0e7a-b45f-5387367791cd'
*/
public function uuid3(): string;
}
28 changes: 28 additions & 0 deletions src/Faker/Generator.php
Expand Up @@ -797,6 +797,34 @@ public function bloodGroup(): string
return $this->ext(Extension\BloodExtension::class)->bloodGroup();
}

/**
* Get a random v3 uuid
*
* @example '7e57d004-2b97-0e7a-b45f-5387367791cd'
*
* @deprecated call uuid3() instead
*/
public function uuid(): string
{
trigger_deprecation(
'fakerphp/faker',
'1.18',
'Method uuid() is deprecated, call uuid3() instead'
);

return $this->uuid3();
}

/**
* Get a random v3 uuid
*
* @example '7e57d004-2b97-0e7a-b45f-5387367791cd'
*/
public function uuid3(): string
{
return $this->ext(Extension\UuidExtension::class)->uuid3();
}

/**
* Get a random EAN13 barcode.
*
Expand Down
29 changes: 29 additions & 0 deletions test/Faker/Core/UuidTest.php
@@ -0,0 +1,29 @@
<?php

namespace Faker\Test\Core;

use Faker\Test\TestCase;

final class UuidTest extends TestCase
{
public function testUuidReturnsUuid()
{
$uuid = $this->faker->uuid3();
self::assertTrue($this->isUuid($uuid));
}

public function testUuidExpectedSeed()
{
if (pack('L', 0x6162797A) == pack('N', 0x6162797A)) {
self::markTestSkipped('Big Endian');
}
$this->faker->seed(123);
self::assertEquals('8e2e0c84-50dd-367c-9e66-f3ab455c78d6', $this->faker->uuid3());
self::assertEquals('073eb60a-902c-30ab-93d0-a94db371f6c8', $this->faker->uuid3());
}

protected function isUuid($uuid)
{
return is_string($uuid) && (bool) preg_match('/^[a-f0-9]{8,8}-(?:[a-f0-9]{4,4}-){3,3}[a-f0-9]{12,12}$/i', $uuid);
}
}

0 comments on commit 0e8aec4

Please sign in to comment.