Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   1  <?php
   2  /**
   3   * Stream filter class to compute the CRC32 value of a string.
   4   *
   5   * Usage:
   6   * <pre>
   7   *   $params = new stdClass;
   8   *   stream_filter_register('horde_crc32', 'Horde_Stream_Filter_Crc32');
   9   *   stream_filter_[app|pre]pend($stream, 'horde_crc32',
  10   *                               [ STREAM_FILTER_[READ|WRITE|ALL] ],
  11   *                               [ $params ]);
  12   *   while (fread($stream, 8192)) {}
  13   *   // CRC32 data in $params->crc32
  14   * </pre>
  15   *
  16   * Copyright 2011-2017 Horde LLC (http://www.horde.org/)
  17   *
  18   * See the enclosed file LICENSE for license information (LGPL). If you
  19   * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  20   *
  21   * @author   Michael Slusarz <slusarz@horde.org>
  22   * @category Horde
  23   * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
  24   * @package  Stream_Filter
  25   */
  26  class Horde_Stream_Filter_Crc32 extends php_user_filter
  27  {
  28      /**
  29       * @see stream_filter_register()
  30       */
  31      #[ReturnTypeWillChange]
  32      public function onCreate()
  33      {
  34          $this->params->crc32 = 0;
  35  
  36          return true;
  37      }
  38  
  39      /**
  40       * @see stream_filter_register()
  41       */
  42      #[ReturnTypeWillChange]
  43      public function filter($in, $out, &$consumed, $closing)
  44      {
  45          while ($bucket = stream_bucket_make_writeable($in)) {
  46              $consumed += $bucket->datalen;
  47              $this->params->crc32 = $this->_crc32Combine($this->params->crc32, crc32($bucket->data), $bucket->datalen);
  48              stream_bucket_append($out, $bucket);
  49          }
  50  
  51          return PSFS_PASS_ON;
  52      }
  53  
  54      /**
  55       */
  56      protected function _crc32Combine($crc1, $crc2, $len2)
  57      {
  58          $odd = array(0xedb88320);
  59          $row = 1;
  60  
  61          for ($n = 1; $n < 32; ++$n) {
  62              $odd[$n] = $row;
  63              $row <<= 1;
  64          }
  65  
  66          $this->_gf2MatrixSquare($even, $odd);
  67          $this->_gf2MatrixSquare($odd, $even);
  68  
  69          do {
  70              /* Apply zeros operator for this bit of len2. */
  71              $this->_gf2MatrixSquare($even, $odd);
  72  
  73              if ($len2 & 1) {
  74                  $crc1 = $this->_gf2MatrixTimes($even, $crc1);
  75              }
  76  
  77              $len2>>=1;
  78  
  79              /* If no more bits set, then done. */
  80              if ($len2 == 0) {
  81                  break;
  82              }
  83  
  84              /* Another iteration of the loop with odd and even swapped. */
  85              $this->_gf2MatrixSquare($odd, $even);
  86              if ($len2 & 1) {
  87                  $crc1 = $this->_gf2MatrixTimes($odd, $crc1);
  88              }
  89  
  90              $len2>>= 1;
  91          } while ($len2 != 0);
  92  
  93          $crc1 ^= $crc2;
  94  
  95          return $crc1;
  96      }
  97  
  98      /**
  99       */
 100      protected function _gf2MatrixSquare(&$square, &$mat)
 101      {
 102          for ($n = 0; $n < 32; ++$n) {
 103              $square[$n] = $this->_gf2MatrixTimes($mat, $mat[$n]);
 104          }
 105      }
 106  
 107      /**
 108       */
 109      protected function _gf2MatrixTimes($mat, $vec)
 110      {
 111          $i = $sum = 0;
 112  
 113          while ($vec) {
 114              if ($vec & 1) {
 115                  $sum ^= $mat[$i];
 116              }
 117  
 118              $vec = ($vec >> 1) & 0x7FFFFFFF;
 119              ++$i;
 120          }
 121  
 122          return $sum;
 123      }
 124  
 125  }