Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]

   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      public function onCreate()
  32      {
  33          $this->params->crc32 = 0;
  34  
  35          return true;
  36      }
  37  
  38      /**
  39       * @see stream_filter_register()
  40       */
  41      public function filter($in, $out, &$consumed, $closing)
  42      {
  43          while ($bucket = stream_bucket_make_writeable($in)) {
  44              $consumed += $bucket->datalen;
  45              $this->params->crc32 = $this->_crc32Combine($this->params->crc32, crc32($bucket->data), $bucket->datalen);
  46              stream_bucket_append($out, $bucket);
  47          }
  48  
  49          return PSFS_PASS_ON;
  50      }
  51  
  52      /**
  53       */
  54      protected function _crc32Combine($crc1, $crc2, $len2)
  55      {
  56          $odd = array(0xedb88320);
  57          $row = 1;
  58  
  59          for ($n = 1; $n < 32; ++$n) {
  60              $odd[$n] = $row;
  61              $row <<= 1;
  62          }
  63  
  64          $this->_gf2MatrixSquare($even, $odd);
  65          $this->_gf2MatrixSquare($odd, $even);
  66  
  67          do {
  68              /* Apply zeros operator for this bit of len2. */
  69              $this->_gf2MatrixSquare($even, $odd);
  70  
  71              if ($len2 & 1) {
  72                  $crc1 = $this->_gf2MatrixTimes($even, $crc1);
  73              }
  74  
  75              $len2>>=1;
  76  
  77              /* If no more bits set, then done. */
  78              if ($len2 == 0) {
  79                  break;
  80              }
  81  
  82              /* Another iteration of the loop with odd and even swapped. */
  83              $this->_gf2MatrixSquare($odd, $even);
  84              if ($len2 & 1) {
  85                  $crc1 = $this->_gf2MatrixTimes($odd, $crc1);
  86              }
  87  
  88              $len2>>= 1;
  89          } while ($len2 != 0);
  90  
  91          $crc1 ^= $crc2;
  92  
  93          return $crc1;
  94      }
  95  
  96      /**
  97       */
  98      protected function _gf2MatrixSquare(&$square, &$mat)
  99      {
 100          for ($n = 0; $n < 32; ++$n) {
 101              $square[$n] = $this->_gf2MatrixTimes($mat, $mat[$n]);
 102          }
 103      }
 104  
 105      /**
 106       */
 107      protected function _gf2MatrixTimes($mat, $vec)
 108      {
 109          $i = $sum = 0;
 110  
 111          while ($vec) {
 112              if ($vec & 1) {
 113                  $sum ^= $mat[$i];
 114              }
 115  
 116              $vec = ($vec >> 1) & 0x7FFFFFFF;
 117              ++$i;
 118          }
 119  
 120          return $sum;
 121      }
 122  
 123  }