Skip to content

Commit 8dfc1c1

Browse files
committed
- UUID: adds toBase64() and fromBase64() methods
1 parent 5d9eaa6 commit 8dfc1c1

File tree

5 files changed

+116
-12
lines changed

5 files changed

+116
-12
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ Class UUID generates Universally Unique Identifiers following the [RFC 4122][rfc
134134
- `v5(string $namespace, string $name): string`
135135
- `valid(string $uuid): bool`
136136
- `matches(string $uuid, int $version = 4): bool`
137+
- `toBase64(string $uuid): string`
138+
- `fromBase64(string $base64): string`
137139

138140
Functions
139141
---------

UUID.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313

1414
use AssertionError;
1515
use InvalidArgumentException;
16+
use function base64_decode;
17+
use function base64_encode;
1618
use function chr;
1719
use function ctype_digit;
1820
use function ctype_xdigit;
1921
use function dechex;
2022
use function explode;
2123
use function gethostbyname;
2224
use function gettimeofday;
25+
use function hex2bin;
2326
use function hexdec;
2427
use function in_array;
2528
use function md5;
@@ -251,7 +254,46 @@ public static function v1(string|int $address = null): string
251254
}
252255

253256
/**
254-
* Creates the v3 and/or v5 UUID.
257+
* Creates a base64 string out of the UUID.
258+
*
259+
* @param string $uuid UUID string
260+
*
261+
* @return string base64 encoded string
262+
*/
263+
public static function toBase64(string $uuid): string
264+
{
265+
if (false === UUID::valid($uuid)) {
266+
throw new InvalidArgumentException('Invalid UUID ' . $uuid);
267+
}
268+
return str_replace(['/', '+', '='], ['-', '_', ''],
269+
base64_encode(hex2bin(str_replace('-', '', $uuid)))
270+
);
271+
}
272+
273+
/**
274+
* Converts a base64 string to UUID.
275+
*
276+
* @param string $base64
277+
*
278+
* @return string UUID string
279+
*/
280+
public static function fromBase64(string $base64): string
281+
{
282+
$uuid = base64_decode(str_replace(
283+
['-', '_', '='], ['/', '+', ''], $base64) . '=='
284+
);
285+
if (!preg_match('//u', $uuid)) {
286+
$uuid = vsprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', unpack('n*', $uuid));
287+
}
288+
if (UUID::valid($uuid)) {
289+
return $uuid;
290+
}
291+
throw new InvalidArgumentException(
292+
'Failed to convert base 64 string to UUID');
293+
}
294+
295+
/**
296+
* Creates a v3 or v5 UUID.
255297
*
256298
* @param string $namespace UUID namespace identifier (see UUID constants)
257299
* @param string $name A name

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.0.2
1+
6.1.0

tests/UUIDTest.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,13 @@ public function method_matches_fails_on_unsupported_uuid_version()
133133
$this->expectExceptionMessage('Expected UUID version 1, 3, 4 or 5 (got 0)');
134134
UUID::matches(UUID::NAMESPACE_OID, 0);
135135
}
136-
137-
/**
138-
* @test
139-
*/
140-
public function verify_uuid_regex()
141-
{
142-
$this->assertFalse(UUID::valid('00000000-0000-2000-0000-000000000000'));
143-
}
144-
136+
145137
/**
146138
* @test
147139
*/
148140
public function verify_uuid4()
149141
{
142+
$this->assertFalse(UUID::valid('00000000-0000-a000-0000-000000000000'));
150143
$this->assertFalse(UUID::valid('00000000-0000-4000-0000-000000000000'));
151144
$this->assertTrue(UUID::valid('00000000-0000-4000-a000-000000000000'));
152145
}
@@ -156,6 +149,9 @@ public function verify_uuid4()
156149
*/
157150
public function issue7()
158151
{
159-
$this->assertSame('1cb8bac3-bb8e-3973-93dc-5119246f0585', UUID::v3(UUID::NAMESPACE_URL, 'fubar'));
152+
$this->assertSame(
153+
'1cb8bac3-bb8e-3973-93dc-5119246f0585',
154+
UUID::v3(UUID::NAMESPACE_URL, 'fubar')
155+
);
160156
}
161157
}

tests/UUIDbase64Test.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Tests\Koded\Stdlib;
4+
5+
use InvalidArgumentException;
6+
use Koded\Stdlib\UUID;
7+
use PHPUnit\Framework\TestCase;
8+
9+
class UUIDbase64Test extends TestCase
10+
{
11+
/**
12+
* @dataProvider base64Binary
13+
*/
14+
public function test_base64_binary_encoded($uuid, $base64)
15+
{
16+
$encoded = UUID::toBase64($uuid);
17+
$decoded = UUID::fromBase64($encoded);
18+
19+
$this->assertSame($base64, $encoded);
20+
$this->assertSame($uuid, $decoded);;
21+
}
22+
23+
/**
24+
* @dataProvider base64Plain
25+
*/
26+
public function test_base64_plain_encoded($uuid, $base64)
27+
{
28+
$this->assertSame($uuid, UUID::fromBase64($base64));;
29+
}
30+
31+
public function test_to_base64_exception()
32+
{
33+
$this->expectException(InvalidArgumentException::class);
34+
$this->expectExceptionMessage('Invalid UUID 0');
35+
UUID::toBase64('0');
36+
}
37+
38+
public function test_from_base64_exception()
39+
{
40+
$this->expectException(InvalidArgumentException::class);
41+
$this->expectExceptionMessage('Failed to convert base 64 string to UUID');
42+
UUID::fromBase64('0');
43+
}
44+
45+
public function base64Binary()
46+
{
47+
return [
48+
// with hex2bin
49+
['e6421c02-1aab-499b-9123-ef02d69f49ba', '5kIcAhqrSZuRI_8C1p9Jug'],
50+
['524d188a-756d-453b-8af5-674a7291197d', 'Uk0YinVtRTuK9WdKcpEZfQ'],
51+
['ed67a863-ff19-475a-a67d-9f9eb63e4dce', '7WeoY-8ZR1qmfZ_etj5Nzg'],
52+
];
53+
}
54+
55+
public function base64Plain()
56+
{
57+
return [
58+
// only base64 encoded
59+
['e6421c02-1aab-499b-9123-ef02d69f49ba', 'ZTY0MjFjMDItMWFhYi00OTliLTkxMjMtZWYwMmQ2OWY0OWJh'],
60+
['524d188a-756d-453b-8af5-674a7291197d', 'NTI0ZDE4OGEtNzU2ZC00NTNiLThhZjUtNjc0YTcyOTExOTdk'],
61+
['ed67a863-ff19-475a-a67d-9f9eb63e4dce', 'ZWQ2N2E4NjMtZmYxOS00NzVhLWE2N2QtOWY5ZWI2M2U0ZGNl'],
62+
];
63+
}
64+
}

0 commit comments

Comments
 (0)