From fadf080cce878db9dd28af1997883d96ef0ef779 Mon Sep 17 00:00:00 2001 From: Benjamin Morel Date: Tue, 18 Aug 2020 18:28:24 +0200 Subject: [PATCH] Fix bug in BigInteger::toBytes() --- src/BigInteger.php | 18 ++++++++++++------ tests/BigIntegerTest.php | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/BigInteger.php b/src/BigInteger.php index 1d53da0..5607560 100644 --- a/src/BigInteger.php +++ b/src/BigInteger.php @@ -1092,18 +1092,24 @@ public function toBytes(bool $signed = true) : string throw new NegativeNumberException('Cannot convert a negative number to a byte string when $signed is false.'); } - $pad = function(string $hex) : string { - return (strlen($hex) % 2 !== 0) ? '0' . $hex : $hex; - }; - $hex = $this->abs()->toBase(16); - $hex = $pad($hex); + + if (strlen($hex) % 2 !== 0) { + $hex = '0' . $hex; + } + + $baseHexLength = strlen($hex); if ($signed) { if ($this->isNegative()) { $hex = bin2hex(~hex2bin($hex)); $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); - $hex = $pad($hex); + + $hexLength = strlen($hex); + + if ($hexLength < $baseHexLength) { + $hex = str_repeat('0', $baseHexLength - $hexLength) . $hex; + } if ($hex[0] < '8') { $hex = 'FF' . $hex; diff --git a/tests/BigIntegerTest.php b/tests/BigIntegerTest.php index c6c4f1d..b4b55e0 100644 --- a/tests/BigIntegerTest.php +++ b/tests/BigIntegerTest.php @@ -3519,9 +3519,37 @@ public function testToBytes(string $number, bool $signed, string $expectedByteSt public function providerToBytes() : array { return [ + ['-549755813889', true, 'FF7FFFFFFFFF'], + ['-549755813888', true, '8000000000'], + ['-549755813887', true, '8000000001'], + ['-4294967297', true, 'FEFFFFFFFF'], + ['-4294967296', true, 'FF00000000'], + ['-4294967295', true, 'FF00000001'], + ['-4294836226', true, 'FF0001FFFE'], + ['-4294836225', true, 'FF0001FFFF'], + ['-4294836224', true, 'FF00020000'], + ['-4294836223', true, 'FF00020001'], + ['-2147483650', true, 'FF7FFFFFFE'], + ['-2147483649', true, 'FF7FFFFFFF'], + ['-2147483648', true, '80000000'], + ['-16777217', true, 'FEFFFFFF'], + ['-16777216', true, 'FF000000'], + ['-16777215', true, 'FF000001'], + ['-16777214', true, 'FF000002'], + ['-16776961', true, 'FF0000FF'], + ['-16776960', true, 'FF000100'], + ['-16776959', true, 'FF000101'], + ['-131073', true, 'FDFFFF'], + ['-131072', true, 'FE0000'], + ['-131071', true, 'FE0001'], + ['-65537', true, 'FEFFFF'], + ['-65536', true, 'FF0000'], + ['-65535', true, 'FF0001'], ['-32769', true, 'FF7FFF'], ['-32768', true, '8000'], ['-32767', true, '8001'], + ['-256', true, 'FF00'], + ['-255', true, 'FF01'], ['-129', true, 'FF7F'], ['-128', true, '80'], ['-2', true, 'FE'], @@ -3534,10 +3562,18 @@ public function providerToBytes() : array ['127', true, '7F'], ['128', false, '80'], ['128', true, '0080'], + ['255', false, 'FF'], + ['255', true, '00FF'], ['32767', false, '7FFF'], ['32767', true, '7FFF'], ['32768', false, '8000'], ['32768', true, '008000'], + ['65535', true, '00FFFF'], + ['65535', false, 'FFFF'], + ['8388607', false, '7FFFFF'], + ['8388607', true, '7FFFFF'], + ['16777215', false, 'FFFFFF'], + ['16777215', true, '00FFFFFF'], ['-783409810830859048059', true, 'D588013FBB7EADEB85'], ['3938956672038786165637', false, 'D588013FBB7EADEB85'],