Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fa5d636

Browse filesBrowse files
minor #36070 [Uid] improve base convertion logic (nicolas-grekas)
This PR was merged into the 5.1-dev branch. Discussion ---------- [Uid] improve base convertion logic | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - The new logic is at least twice as fast as the current algo. It's also way more common and generic. Commits ------- 0e05c6d [Uid] improve base convertion logic
2 parents 42c76d7 + 0e05c6d commit fa5d636
Copy full SHA for fa5d636

4 files changed

+101-89Lines changed: 101 additions & 89 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file
+97Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Uid;
13+
14+
/**
15+
* @internal
16+
*
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
class BinaryUtil
20+
{
21+
public const BASE10 = [
22+
'' => '0123456789',
23+
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
24+
];
25+
26+
public static function toBase(string $bytes, array $map): string
27+
{
28+
$base = \strlen($alphabet = $map['']);
29+
$bytes = array_values(unpack(\PHP_INT_SIZE >= 8 ? 'n*' : 'C*', $bytes));
30+
$digits = '';
31+
32+
while ($count = \count($bytes)) {
33+
$quotient = [];
34+
$remainder = 0;
35+
36+
for ($i = 0; $i !== $count; ++$i) {
37+
$carry = $bytes[$i] + ($remainder << (\PHP_INT_SIZE >= 8 ? 16 : 8));
38+
$digit = intdiv($carry, $base);
39+
$remainder = $carry % $base;
40+
41+
if ($digit || $quotient) {
42+
$quotient[] = $digit;
43+
}
44+
}
45+
46+
$digits = $alphabet[$remainder].$digits;
47+
$bytes = $quotient;
48+
}
49+
50+
return $digits;
51+
}
52+
53+
public static function fromBase(string $digits, array $map): string
54+
{
55+
$base = \strlen($map['']);
56+
$count = \strlen($digits);
57+
$bytes = [];
58+
59+
while ($count) {
60+
$quotient = [];
61+
$remainder = 0;
62+
63+
for ($i = 0; $i !== $count; ++$i) {
64+
$carry = ($bytes ? $digits[$i] : $map[$digits[$i]]) + $remainder * $base;
65+
66+
if (\PHP_INT_SIZE >= 8) {
67+
$digit = $carry >> 16;
68+
$remainder = $carry & 0xFFFF;
69+
} else {
70+
$digit = $carry >> 8;
71+
$remainder = $carry & 0xFF;
72+
}
73+
74+
if ($digit || $quotient) {
75+
$quotient[] = $digit;
76+
}
77+
}
78+
79+
$bytes[] = $remainder;
80+
$count = \count($digits = $quotient);
81+
}
82+
83+
return pack(\PHP_INT_SIZE >= 8 ? 'n*' : 'C*', ...array_reverse($bytes));
84+
}
85+
86+
public static function add(string $a, string $b): string
87+
{
88+
$carry = 0;
89+
for ($i = 7; 0 <= $i; --$i) {
90+
$carry += \ord($a[$i]) + \ord($b[$i]);
91+
$a[$i] = \chr($carry & 0xFF);
92+
$carry >>= 8;
93+
}
94+
95+
return $a;
96+
}
97+
}
Collapse file

‎src/Symfony/Component/Uid/InternalUtil.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Uid/InternalUtil.php
-85Lines changed: 0 additions & 85 deletions
This file was deleted.
Collapse file

‎src/Symfony/Component/Uid/Ulid.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Uid/Ulid.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function getTime(): float
121121
base_convert(substr($time, 6, 4), 32, 16)
122122
);
123123

124-
return InternalUtil::toDecimal(hex2bin($time)) / 1000;
124+
return BinaryUtil::toBase(hex2bin($time), BinaryUtil::BASE10) / 1000;
125125
}
126126

127127
public function __toString(): string
@@ -163,7 +163,7 @@ private static function generate(): string
163163
if (\PHP_INT_SIZE >= 8) {
164164
$time = base_convert($time, 10, 32);
165165
} else {
166-
$time = bin2hex(InternalUtil::toBinary($time));
166+
$time = bin2hex(BinaryUtil::fromBase($time, BinaryUtil::BASE10));
167167
$time = sprintf('%s%04s%04s',
168168
base_convert(substr($time, 0, 2), 16, 32),
169169
base_convert(substr($time, 2, 5), 16, 32),
Collapse file

‎src/Symfony/Component/Uid/Uuid.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Uid/Uuid.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ public function getTime(): float
121121
}
122122

123123
$time = str_pad(hex2bin($time), 8, "\0", STR_PAD_LEFT);
124-
$time = InternalUtil::binaryAdd($time, self::TIME_OFFSET_COM);
124+
$time = BinaryUtil::add($time, self::TIME_OFFSET_COM);
125125
$time[0] = $time[0] & "\x7F";
126126

127-
return InternalUtil::toDecimal($time) / 10000000;
127+
return BinaryUtil::toBase($time, BinaryUtil::BASE10) / 10000000;
128128
}
129129

130130
public function getMac(): string

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.