Overview

Packages

  • Stream
    • Filter

Classes

  • Horde_Stream_Filter_Bin2hex
  • Horde_Stream_Filter_Crc32
  • Horde_Stream_Filter_Eol
  • Overview
  • Package
  • Class
  • Tree
  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-2012 Horde LLC (http://www.horde.org/)
 17:  *
 18:  * See the enclosed file COPYING 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: }
124: 
API documentation generated by ApiGen