8000 [Uid] Add fromBase58(), fromBase32(), fromRfc4122() and fromBinary() … · symfony/symfony@2b48090 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2b48090

Browse files
committed
[Uid] Add fromBase58(), fromBase32(), fromRfc4122() and fromBinary() methods
1 parent 4818b28 commit 2b48090

File tree

6 files changed

+342
-0
lines changed

6 files changed

+342
-0
lines changed

src/Symfony/Component/Uid/AbstractUid.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,34 @@ abstract public static function isValid(string $uid): bool;
3737
*/
3838
abstract public static function fromString(string $uid): self;
3939

40+
/**
41+
* @return static
42+
*
43+
* @throws \InvalidArgumentException When the passed value is not valid
44+
*/
45+
abstract public static function fromBinary(string $uid): self;
46+
47+
/**
48+
* @return static
49+
*
50+
* @throws \InvalidArgumentException When the passed value is not valid
51+
*/
52+
abstract public static function fromBase58(string $uid): self;
53+
54+
/**
55+
* @return static
56+
*
57+
* @throws \InvalidArgumentException When the passed value is not valid
58+
*/
59+
abstract public static function fromBase32(string $uid): self;
60+
61+
/**
62+
* @return static
63+
*
64+
* @throws \InvalidArgumentException When the passed value is not valid
65+
*/
66+
abstract public static function fromRfc4122(string $uid): self;
67+
4068
/**
4169
* Returns the identifier as a raw binary string.
4270
*/

src/Symfony/Component/Uid/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.3.0
5+
-----
6+
7+
* added `AbstractUid::fromBinary()`, `AbstractUid::fromBase58()`, `AbstractUid::fromBase32()` and `AbstractUid::fromRfc4122()` methods
8+
49
5.2.0
510
-----
611

src/Symfony/Component/Uid/Tests/UlidTest.php

Lines changed: 92 additions & 0 deletions
< A93C tr class="diff-line-row">
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,96 @@ public function testCompare()
118118
$this->assertLessThan(0, $b->compare($c));
119119
$this->assertGreaterThan(0, $c->compare($b));
120120
}
121+
122+
public function testFromBinary()
123+
{
124+
$this->assertEquals(
125+
Ulid::fromString("\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08"),
126+
Ulid::fromBinary("\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08")
127+
);
128+
129+
foreach ([
130+
'01EW2RYKDCT2SAK454KBR2QG08',
131+
'1BVXue8CnY8ogucrHX3TeF',
132+
'0177058f-4dac-d0b2-a990-a49af02bc008',
133+
] as $ulid) {
134+
try {
135+
Ulid::fromBinary($ulid);
136+
137+
$this->fail();
138+
} catch (\Throwable $e) {
139+
}
140+
141+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
142+
}
143+
}
144+
145+
public function testFromBase58()
146+
{
147+
$this->assertEquals(
148+
Ulid::fromString('1BVXue8CnY8ogucrHX3TeF'),
149+
Ulid::fromBase58('1BVXue8CnY8ogucrHX3TeF')
150+
);
151+
152+
foreach ([
153+
"\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08",
154+
'01EW2RYKDCT2SAK454KBR2QG08',
155+
'0177058f-4dac-d0b2-a990-a49af02bc008',
156+
] as $ulid) {
157+
try {
158+
Ulid::fromBase58($ulid);
159+
160+
$this->fail();
161+
} catch (\Throwable $e) {
162+
}
163+
164+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
165+
}
166+
}
167+
168+
public function testFromBase32()
169+
{
170+
$this->assertEquals(
171+
Ulid::fromString('01EW2RYKDCT2SAK454KBR2QG08'),
172+
Ulid::fromBase32('01EW2RYKDCT2SAK454KBR2QG08')
173+
);
174+
175+
foreach ([
176+
"\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08",
177+
'1BVXue8CnY8ogucrHX3TeF',
178+
'0177058f-4dac-d0b2-a990-a49af02bc008',
179+
] as $ulid) {
180+
try {
181+
Ulid::fromBase32($ulid);
182+
183+
$this->fail();
184+
} catch (\Throwable $e) {
185+
}
186+
187+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
188+
}
189+
}
190+
191+
public function testFromRfc4122()
192+
{
193+
$this->assertEquals(
194+
Ulid::fromString('0177058f-4dac-d0b2-a990-a49af02bc008'),
195+
Ulid::fromRfc4122('0177058f-4dac-d0b2-a990-a49af02bc008')
196+
);
197+
198+
foreach ([
199+
"\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08",
200+
'01EW2RYKDCT2SAK454KBR2QG08',
201+
'1BVXue8CnY8ogucrHX3TeF',
202+
] as $ulid) {
203+
try {
204+
Ulid::fromRfc4122($ulid);
205+
206+
$this->fail();
207+
} catch (\Throwable $e) {
208+
}
209+
210+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
211+
}
212+
}
121213
}

src/Symfony/Component/Uid/Tests/UuidTest.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,96 @@ public function testNilUuid()
193193
$this->assertInstanceOf(NilUuid::class, $uuid);
194194
$this->assertSame('00000000-0000-0000-0000-000000000000', (string) $uuid);
195195
}
196+
197+
public function testFromBinary()
198+
{
199+
$this->assertEquals(
200+
Uuid::fromString("\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08"),
201+
Uuid::fromBinary("\x01\x77\x05\x8F\x4D\xAC\xD0\xB2\xA9\x90\xA4\x9A\xF0\x2B\xC0\x08")
202+
);
203+
204+
foreach ([
205+
'01EW2RYKDCT2SAK454KBR2QG08',
206+
'1BVXue8CnY8ogucrHX3TeF',
207+
'0177058f-4dac-d0b2-a990-a49af02bc008',
208+
] as $ulid) {
209+
try {
210+
Uuid::fromBinary($ulid);
211+
212+
$this->fail();
213+
} catch (\Throwable $e) {
214+
}
215+
216+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
217+
}
218+
}
219+
220+
public function testFromBase58()
221+
{
222+
$this->assertEquals(
223+
UuidV1::fromString('94fSqj9oxGtsNbkfQNntwx'),
224+
UuidV1::fromBase58('94fSqj9oxGtsNbkfQNntwx')
225+
);
226+
227+
foreach ([
228+
"\x41\x4C\x08\x92\x57\x1B\x11\xEB\xBF\x70\x93\xF9\xB0\x82\x2C\x57",
229+
'219G494NRV27NVYW4KZ6R84B2Q',
230+
'414c0892-571b-11eb-bf70-93f9b0822c57',
231+
] as $ulid) {
232+
try {
233+
UuidV1::fromBase58($ulid);
234+
235+
$this->fail();
236+
} catch (\Throwable $e) {
237+
}
238+
239+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
240+
}
241+
}
242+
243+
public function testFromBase32()
244+
{
245+
$this->assertEquals(
246+
UuidV5::fromString('2VN0S74HBDBB0AQRXAHFVG35KK'),
247+
UuidV5::fromBase32('2VN0S74HBDBB0AQRXAHFVG35KK')
248+
);
249+
250+
foreach ([
251+
"\x5B\xA8\x32\x72\x45\x6D\x5A\xC0\xAB\xE3\xAA\x8B\xF7\x01\x96\x73",
252+
'CKTRYycTes6WAqSQJsTDaz',
253+
'5ba83272-456d-5ac0-abe3-aa8bf7019673',
254+
] as $ulid) {
255+
try {
256+
Ulid::fromBase32($ulid);
257+
258+
$this->fail();
259+
} catch (\Throwable $e) {
260+
}
261+
262+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
263+
}
264+
}
265+
266+
public function testFromRfc4122()
267+
{
268+
$this->assertEquals(
269+
UuidV6::fromString('1eb571b4-14c0-6893-bf70-2d4c83cf755a'),
270+
UuidV6::fromRfc4122('1eb571b4-14c0-6893-bf70-2d4c83cf755a')
271+
);
272+
273+
foreach ([
274+
"\x1E\xB5\x71\xB4\x14\xC0\x68\x93\xBF\x70\x2D\x4C\x83\xCF\x75\x5A",
275+
'0YPNRV8560D29VYW1D9J1WYXAT',
276+
'4nwTLZ2TdMtTVDE5AwVjaR',
277+
] as $ulid) {
278+
try {
279+
Ulid::fromRfc4122($ulid);
280+
281+
$this->fail();
282+
} catch (\Throwable $e) {
283+
}
284+
285+
$this->assertInstanceOf(\InvalidArgumentException::class, $e);
286+
}
287+
}
196288
}

src/Symfony/Component/Uid/Ulid.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,61 @@ public static function fromString(string $ulid): parent
8282
return new self(strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ'));
8383
}
8484

85+
/**
86+
* {@inheritdoc}
87+
*/
88+
public static function fromBinary(string $ulid): parent
89+
{
90+
if (16 !== \strlen($ulid)) {
91+
throw new \InvalidArgumentException();
92+
}
93+
94+
$ulid = bin2hex($ulid);
95+
$ulid = sprintf('%02s%04s%04s%04s%04s%04s%04s',
96+
base_convert(substr($ulid, 0, 2), 16, 32),
97+
base_convert(substr($ulid, 2, 5), 16, 32),
98+
base_convert(substr($ulid, 7, 5), 16, 32),
99+
base_convert(substr($ulid, 12, 5), 16, 32),
100+
base_convert(substr($ulid, 17, 5), 16, 32),
101+
base_convert(substr($ulid, 22, 5), 16, 32),
102+
base_convert(substr($ulid, 27, 5), 16, 32)
103+
);
104+
105+
return new static(strtr($ulid, 'abcdefghijklmnopqrstuv', 'ABCDEFGHJKMNPQRSTVWXYZ'));
106+
}
107+
108+
/**
109+
* {@inheritdoc}
110+
*/
111+
public static function fromBase58(string $ulid): parent
112+
{
113+
if (22 !== \strlen($ulid) || 22 !== strspn($ulid, BinaryUtil::BASE58[''])) {
114+
throw new \InvalidArgumentException();
115+
}
116+
117+
return static::fromBinary(BinaryUtil::fromBase($ulid, BinaryUtil::BASE58));
118+
}
119+
120+
/**
121+
* {@inheritdoc}
122+
*/
123+
public static function fromBase32(string $ulid): parent
124+
{
125+
return new static($ulid);
126+
}
127+
128+
/**
129+
* {@inheritdoc}
130+
*/
131+
public static function fromRfc4122(string $ulid): parent
132+
{
133+
if (36 !== \strlen($ulid) || !Uuid::isValid($ulid)) {
134+
throw new \InvalidArgumentException();
135+
}
136+
137+
return static::fromBinary((new Uuid($ulid))->toBinary());
138+
}
139+
85140
public function toBinary(): string
86141
{
87142
$ulid = strtr($this->uid, 'ABCDEFGHJKMNPQRSTVWXYZ', 'abcdefghijklmnopqrstuv');

src/Symfony/Component/Uid/Uuid.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,76 @@ public static function fromString(string $uuid): parent
7777
return new self($uuid);
7878
}
7979

80+
/**
81+
* {@inheritdoc}
82+
*/
83+
public static function fromBinary(string $uuid): parent
84+
{
85+
if (16 !== \strlen($uuid)) {
86+
throw new \InvalidArgumentException();
87+
}
88+
89+
// don't use uuid_unparse(), it's slower
90+
$uuid = bin2hex($uuid);
91+
$uuid = substr_replace($uuid, '-', 8, 0);
92+
$uuid = substr_replace($uuid, '-', 13, 0);
93+
$uuid = substr_replace($uuid, '-', 18, 0);
94+
$uuid = substr_replace($uuid, '-', 23, 0);
95+
96+
return static::fromRfc4122($uuid);
97+
}
98+
99+
/**
100+
* {@inheritdoc}
101+
*/
102+
public static function fromBase58(string $uuid): parent
103+
{
104+
if (22 !== \strlen($uuid) || 22 !== strspn($uuid, BinaryUtil::BASE58[''])) {
105+
throw new \InvalidArgumentException();
106+
}
107+
108+
return static::fromBinary(BinaryUtil::fromBase($uuid, BinaryUtil::BASE58));
109+
}
110+
111+
/**
112+
* {@inheritdoc}
113+
*/
114+
public static function fromBase32(string $uuid): parent
115+
{
116+
if (26 !== \strlen($uuid) || !Ulid::isValid($uuid)) {
117+
throw new \InvalidArgumentException();
118+
}
119+
120+
return static::fromRfc4122((new Ulid($uuid))->toRfc4122());
121+
}
122+
123+
/**
124+
* {@inheritdoc}
125+
*/
126+
public static function fromRfc4122(string $uuid): parent
127+
{
128+
if (__CLASS__ !== static::class || 36 !== \strlen($uuid)) {
129+
return new static($uuid);
130+
}
131+
132+
try {
133+
$type = uuid_type($uuid);
134+
} catch (\ValueError $e) {
135+
throw new \InvalidArgumentException(sprintf('Invalid UUID%s: "%s".', static::TYPE ? 'v'.static::TYPE : '', $uuid), 0, $e);
136+
}
137+
138+
switch ($type) {
139+
case UuidV1::TYPE: return new UuidV1($uuid);
140+
case UuidV3::TYPE: return new UuidV3($uuid);
141+
case UuidV4::TYPE: return new UuidV4($uuid);
142+
case UuidV5::TYPE: return new UuidV5($uuid);
143+
case UuidV6::TYPE: return new UuidV6($uuid);
144+
case NilUuid::TYPE: return new NilUuid();
145+
}
146+
147+
return new self($uuid);
148+
}
149+
80150
final public static function v1(): UuidV1
81151
{
82152
return new UuidV1();

0 commit comments

Comments
 (0)
0