[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/fgrosse/phpasn1/lib/ASN1/Universal/ -> Integer.php (source)

   1  <?php
   2  /*
   3   * This file is part of the PHPASN1 library.
   4   *
   5   * Copyright © Friedrich Große <[email protected]>
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  namespace FG\ASN1\Universal;
  12  
  13  use Exception;
  14  use FG\Utility\BigInteger;
  15  use FG\ASN1\Exception\ParserException;
  16  use FG\ASN1\ASNObject;
  17  use FG\ASN1\Parsable;
  18  use FG\ASN1\Identifier;
  19  
  20  class Integer extends ASNObject implements Parsable
  21  {
  22      /** @var int */
  23      private $value;
  24  
  25      /**
  26       * @param int $value
  27       *
  28       * @throws Exception if the value is not numeric
  29       */
  30      public function __construct($value)
  31      {
  32          if (is_numeric($value) == false) {
  33              throw new Exception("Invalid VALUE [{$value}] for ASN1_INTEGER");
  34          }
  35          $this->value = $value;
  36      }
  37  
  38      public function getType()
  39      {
  40          return Identifier::INTEGER;
  41      }
  42  
  43      public function getContent()
  44      {
  45          return $this->value;
  46      }
  47  
  48      protected function calculateContentLength()
  49      {
  50          return strlen($this->getEncodedValue());
  51      }
  52  
  53      protected function getEncodedValue()
  54      {
  55          $value = BigInteger::create($this->value, 10);
  56          $negative = $value->compare(0) < 0;
  57          if ($negative) {
  58               $value = $value->absoluteValue();
  59               $limit = 0x80;
  60          } else {
  61               $limit = 0x7f;
  62          }
  63  
  64          $mod = 0xff+1;
  65          $values = [];
  66          while($value->compare($limit) > 0) {
  67              $values[] = $value->modulus($mod)->toInteger();
  68              $value = $value->shiftRight(8);
  69          }
  70  
  71          $values[] = $value->modulus($mod)->toInteger();
  72          $numValues = count($values);
  73  
  74          if ($negative) {
  75              for ($i = 0; $i < $numValues; $i++) {
  76                  $values[$i] = 0xff - $values[$i];
  77              }
  78              for ($i = 0; $i < $numValues; $i++) {
  79                  $values[$i] += 1;
  80                  if ($values[$i] <= 0xff) {
  81                      break;
  82                  }
  83                  assert($i != $numValues - 1);
  84                  $values[$i] = 0;
  85              }
  86              if ($values[$numValues - 1] == 0x7f) {
  87                  $values[] = 0xff;
  88              }
  89          }
  90          $values = array_reverse($values);
  91          $r = pack("C*", ...$values);
  92          return $r;
  93      }
  94  
  95      private static function ensureMinimalEncoding($binaryData, $offsetIndex)
  96      {
  97          // All the first nine bits cannot equal 0 or 1, which would
  98          // be non-minimal encoding for positive and negative integers respectively
  99          if ((ord($binaryData[$offsetIndex]) == 0x00 && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0) ||
 100              (ord($binaryData[$offsetIndex]) == 0xff && (ord($binaryData[$offsetIndex+1]) & 0x80) == 0x80)) {
 101              throw new ParserException("Integer not minimally encoded", $offsetIndex);
 102          }
 103      }
 104  
 105      public static function fromBinary(&$binaryData, &$offsetIndex = 0)
 106      {
 107          $parsedObject = new static(0);
 108          self::parseIdentifier($binaryData[$offsetIndex], $parsedObject->getType(), $offsetIndex++);
 109          $contentLength = self::parseContentLength($binaryData, $offsetIndex, 1);
 110  
 111          if ($contentLength > 1) {
 112              self::ensureMinimalEncoding($binaryData, $offsetIndex);
 113          }
 114          $isNegative = (ord($binaryData[$offsetIndex]) & 0x80) != 0x00;
 115          $number = BigInteger::create(ord($binaryData[$offsetIndex++]) & 0x7F);
 116  
 117          for ($i = 0; $i < $contentLength - 1; $i++) {
 118              $number = $number->multiply(0x100)->add(ord($binaryData[$offsetIndex++]));
 119          }
 120  
 121          if ($isNegative) {
 122              $number = $number->subtract(BigInteger::create(2)->toPower(8 * $contentLength - 1));
 123          }
 124  
 125          $parsedObject = new static((string)$number);
 126          $parsedObject->setContentLength($contentLength);
 127  
 128          return $parsedObject;
 129      }
 130  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer