[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Encrypt/ -> Base32.php (source)

   1  <?php
   2  
   3  /**
   4   * Joomla! Content Management System
   5   *
   6   * @copyright  (C) 2013 Open Source Matters, Inc. <https://www.joomla.org>
   7   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   8   */
   9  
  10  namespace Joomla\CMS\Encrypt;
  11  
  12  // phpcs:disable PSR1.Files.SideEffects
  13  \defined('JPATH_PLATFORM') or die;
  14  // phpcs:enable PSR1.Files.SideEffects
  15  
  16  /**
  17   * Base32 encryption class
  18   *
  19   * @since    1.0
  20   */
  21  class Base32
  22  {
  23      /**
  24       * CSRFC3548
  25       *
  26       * The character set as defined by RFC3548
  27       * @link http://www.ietf.org/rfc/rfc3548.txt
  28       */
  29      public const CSRFC3548 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
  30  
  31      /**
  32       * str2bin
  33       *
  34       * Converts any ascii string to a binary string
  35       *
  36       * @param   string  $str  The string you want to convert
  37       *
  38       * @return  string  String of 0's and 1's
  39       */
  40      private function str2bin($str)
  41      {
  42          $chrs = unpack('C*', $str);
  43  
  44          return vsprintf(str_repeat('%08b', \count($chrs)), $chrs);
  45      }
  46  
  47      /**
  48       * bin2str
  49       *
  50       * Converts a binary string to an ascii string
  51       *
  52       * @param   string  $str  The string of 0's and 1's you want to convert
  53       *
  54       * @return  string  The ascii output
  55       *
  56       * @throws \Exception
  57       */
  58      private function bin2str($str)
  59      {
  60          if (\strlen($str) % 8 > 0) {
  61              throw new \Exception('Length must be divisible by 8');
  62          }
  63  
  64          if (!preg_match('/^[01]+$/', $str)) {
  65              throw new \Exception('Only 0\'s and 1\'s are permitted');
  66          }
  67  
  68          preg_match_all('/.{8}/', $str, $chrs);
  69          $chrs = array_map('bindec', $chrs[0]);
  70  
  71          // I'm just being slack here
  72          array_unshift($chrs, 'C*');
  73  
  74          return \call_user_func_array('pack', $chrs);
  75      }
  76  
  77      /**
  78       * fromBin
  79       *
  80       * Converts a correct binary string to base32
  81       *
  82       * @param   string  $str  The string of 0's and 1's you want to convert
  83       *
  84       * @return  string  String encoded as base32
  85       *
  86       * @throws  \Exception
  87       */
  88      private function fromBin($str)
  89      {
  90          if (\strlen($str) % 8 > 0) {
  91              throw new \Exception('Length must be divisible by 8');
  92          }
  93  
  94          if (!preg_match('/^[01]+$/', $str)) {
  95              throw new \Exception('Only 0\'s and 1\'s are permitted');
  96          }
  97  
  98          // Base32 works on the first 5 bits of a byte, so we insert blanks to pad it out
  99          $str = preg_replace('/(.{5})/', '000$1', $str);
 100  
 101          // We need a string divisible by 5
 102          $length = \strlen($str);
 103          $rbits = $length & 7;
 104  
 105          if ($rbits > 0) {
 106              // Excessive bits need to be padded
 107              $ebits = substr($str, $length - $rbits);
 108              $str = substr($str, 0, $length - $rbits);
 109              $str .= "000$ebits" . str_repeat('0', 5 - \strlen($ebits));
 110          }
 111  
 112          preg_match_all('/.{8}/', $str, $chrs);
 113          $chrs = array_map(array($this, '_mapcharset'), $chrs[0]);
 114  
 115          return implode('', $chrs);
 116      }
 117  
 118      /**
 119       * toBin
 120       *
 121       * Accepts a base32 string and returns an ascii binary string
 122       *
 123       * @param   string  $str  The base32 string to convert
 124       *
 125       * @return  string  Ascii binary string
 126       *
 127       * @throws  \Exception
 128       */
 129      private function toBin($str)
 130      {
 131          if (!preg_match('/^[' . self::CSRFC3548 . ']+$/', $str)) {
 132              throw new \Exception('Must match character set');
 133          }
 134  
 135          // Convert the base32 string back to a binary string
 136          $str = implode('', array_map(array($this, '_mapbin'), str_split($str)));
 137  
 138          // Remove the extra 0's we added
 139          $str = preg_replace('/000(.{5})/', '$1', $str);
 140  
 141          // Unpad if necessary
 142          $length = \strlen($str);
 143          $rbits = $length & 7;
 144  
 145          if ($rbits > 0) {
 146              $str = substr($str, 0, $length - $rbits);
 147          }
 148  
 149          return $str;
 150      }
 151  
 152      /**
 153       * fromString
 154       *
 155       * Convert any string to a base32 string
 156       * This should be binary safe...
 157       *
 158       * @param   string  $str  The string to convert
 159       *
 160       * @return  string  The converted base32 string
 161       */
 162      public function encode($str)
 163      {
 164          return $this->fromBin($this->str2bin($str));
 165      }
 166  
 167      /**
 168       * toString
 169       *
 170       * Convert any base32 string to a normal sctring
 171       * This should be binary safe...
 172       *
 173       * @param   string  $str  The base32 string to convert
 174       *
 175       * @return  string  The normal string
 176       */
 177      public function decode($str)
 178      {
 179          $str = strtoupper($str);
 180  
 181          return $this->bin2str($this->toBin($str));
 182      }
 183  
 184      /**
 185       * _mapcharset
 186       *
 187       * Used with array_map to map the bits from a binary string
 188       * directly into a base32 character set
 189       *
 190       * @param   string  $str  The string of 0's and 1's you want to convert
 191       *
 192       * @return  string  Resulting base32 character
 193       *
 194       * @access private
 195       */
 196      private function _mapcharset($str)
 197      {
 198          // Huh!
 199          $x = self::CSRFC3548;
 200  
 201          return $x[bindec($str)];
 202      }
 203  
 204      /**
 205       * _mapbin
 206       *
 207       * Used with array_map to map the characters from a base32
 208       * character set directly into a binary string
 209       *
 210       * @param   string  $chr  The character to map
 211       *
 212       * @return  string  String of 0's and 1's
 213       *
 214       * @access private
 215       */
 216      private function _mapbin($chr)
 217      {
 218          return sprintf('%08b', strpos(self::CSRFC3548, $chr));
 219      }
 220  }


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