From 1dcbb03898e1a6a705a884a5ef1fc20959604e5e Mon Sep 17 00:00:00 2001 From: Alexander Danilov Date: Sat, 25 Jul 2026 09:42:20 +0000 Subject: [PATCH] Optimize Decoder: Replace string concatenation loops with array/implode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace inefficient string concatenation in loops with array append and implode pattern. This changes O(n²) string operations to O(n). - In parseBinaryIdentifier(): collect identifier octets in array then implode once instead of concatenating in loop - In parseContentLength(): collect length octets in array then implode once instead of concatenating in loop This optimization is especially beneficial when parsing long-form identifiers and content lengths, which are common in X.509 and complex ASN.1 structures. --- src/ASN1/Decoder/Decoder.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ASN1/Decoder/Decoder.php b/src/ASN1/Decoder/Decoder.php index a55d1fc..73d9eed 100644 --- a/src/ASN1/Decoder/Decoder.php +++ b/src/ASN1/Decoder/Decoder.php @@ -189,6 +189,7 @@ protected function parseBinaryIdentifier($binaryData, &$offsetIndex) return $identifier; } + $identifierParts = [$identifier]; while (true) { if (\strlen($binaryData) <= $offsetIndex) { throw new ParserException( @@ -196,8 +197,8 @@ protected function parseBinaryIdentifier($binaryData, &$offsetIndex) $offsetIndex ); } - $nextOctet = $binaryData[$offsetIndex++]; - $identifier .= $nextOctet; + $nextOctet = $binaryData[$offsetIndex++]; + $identifierParts[] = $nextOctet; if ((\ord($nextOctet) & 0x80) === 0) { // the most significant bit is 0 to we have reached the end of the identifier @@ -205,7 +206,7 @@ protected function parseBinaryIdentifier($binaryData, &$offsetIndex) } } - return $identifier; + return \implode('', $identifierParts); } protected function parseContentLength(&$binaryData, &$offsetIndex) @@ -223,6 +224,7 @@ protected function parseContentLength(&$binaryData, &$offsetIndex) if (($firstOctet & 0x80) != 0) { // bit 8 is set -> this is the long form $nrOfLengthOctets = $firstOctet & 0x7F; + $octets = [$contentLengthOctets]; for ($i = 0; $i < $nrOfLengthOctets; $i++) { if (\strlen($binaryData) <= $offsetIndex) { throw new ParserException( @@ -230,8 +232,9 @@ protected function parseContentLength(&$binaryData, &$offsetIndex) $offsetIndex ); } - $contentLengthOctets .= $binaryData[$offsetIndex++]; + $octets[] = $binaryData[$offsetIndex++]; } + $contentLengthOctets = \implode('', $octets); } return $contentLengthOctets;