pburggraf /
CRC
| 1 | <?php |
||
| 2 | |||
| 3 | declare(strict_types=1); |
||
| 4 | |||
| 5 | namespace PBurggraf\CRC; |
||
| 6 | |||
| 7 | /** |
||
| 8 | * @author Philip Burggraf <[email protected]> |
||
| 9 | */ |
||
| 10 | abstract class AbstractCRC |
||
| 11 | { |
||
| 12 | protected int $poly; |
||
| 13 | |||
| 14 | protected int $init; |
||
| 15 | |||
| 16 | protected bool $reverseIn; |
||
| 17 | |||
| 18 | protected bool $reverseOut; |
||
| 19 | |||
| 20 | protected int $xorOut; |
||
| 21 | |||
| 22 | protected int $bitLength; |
||
| 23 | |||
| 24 | public function calculate(string $buffer): int |
||
| 25 | { |
||
| 26 | $bufferLength = \strlen($buffer); |
||
| 27 | |||
| 28 | $mask = (((1 << ($this->bitLength - 1)) - 1) << 1) | 1; |
||
| 29 | $highBit = 1 << ($this->bitLength - 1); |
||
| 30 | |||
| 31 | $crc = $this->init; |
||
| 32 | |||
| 33 | for ($iterator = 0; $iterator < $bufferLength; ++$iterator) { |
||
| 34 | $character = \ord($buffer[$iterator]); |
||
| 35 | if ($this->reverseIn) { |
||
| 36 | $character = $this->binaryReverse($character, 8); |
||
| 37 | } |
||
| 38 | |||
| 39 | for ($j = 0x80; $j; $j >>= 1) { |
||
| 40 | $bit = $crc & $highBit; |
||
| 41 | $crc <<= 1; |
||
| 42 | |||
| 43 | if ($character & $j) { |
||
| 44 | $bit ^= $highBit; |
||
| 45 | } |
||
| 46 | |||
| 47 | if ($bit) { |
||
| 48 | $crc ^= $this->poly; |
||
| 49 | } |
||
| 50 | } |
||
| 51 | } |
||
| 52 | |||
| 53 | if ($this->reverseOut) { |
||
| 54 | $crc = $this->binaryReverse($crc, $this->bitLength); |
||
| 55 | } |
||
| 56 | |||
| 57 | $crc ^= $this->xorOut; |
||
| 58 | |||
| 59 | return $crc & $mask; |
||
| 60 | } |
||
| 61 | |||
| 62 | public function calculateWithTable(string $buffer, array $table): int |
||
| 63 | { |
||
| 64 | $bufferLength = \strlen($buffer); |
||
| 65 | |||
| 66 | if (count($table) !== 256) { |
||
| 67 | throw new \InvalidArgumentException('CRC lookup table not populated'); |
||
| 68 | } |
||
| 69 | |||
| 70 | $mask = (((1 << ($this->bitLength - 1)) - 1) << 1) | 1; |
||
| 71 | $highBit = 1 << ($this->bitLength - 1); |
||
|
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
| 72 | |||
| 73 | $crc = $this->init; |
||
| 74 | |||
| 75 | for ($iterator = 0; $iterator < $bufferLength; ++$iterator) { |
||
| 76 | $character = \ord($buffer[$iterator]); |
||
| 77 | if ($this->reverseIn) { |
||
| 78 | $character = $this->binaryReverse($character, 8); |
||
| 79 | } |
||
| 80 | |||
| 81 | $tableValue = $table[(($crc >> ($this->bitLength - 8)) ^ $character) & 0xFF]; |
||
| 82 | |||
| 83 | if (($this->bitLength - 8) !== 0) { |
||
| 84 | $tableValue ^= ($crc << 8); |
||
| 85 | } |
||
| 86 | |||
| 87 | $crc = $tableValue; |
||
| 88 | $crc &= $mask; |
||
| 89 | } |
||
| 90 | |||
| 91 | if ($this->reverseOut) { |
||
| 92 | $crc = $this->binaryReverse($crc, $this->bitLength); |
||
| 93 | } |
||
| 94 | |||
| 95 | $crc ^= $this->xorOut; |
||
| 96 | |||
| 97 | return $crc & $mask; |
||
| 98 | } |
||
| 99 | |||
| 100 | /** |
||
| 101 | * @return int[] |
||
| 102 | */ |
||
| 103 | public function populateTable(): array |
||
| 104 | { |
||
| 105 | $tableSize = 256; |
||
| 106 | |||
| 107 | $mask = (((1 << ($this->bitLength - 1)) - 1) << 1) | 1; |
||
| 108 | $highBit = 1 << ($this->bitLength - 1); |
||
| 109 | |||
| 110 | $table = []; |
||
| 111 | |||
| 112 | for ($iterator = 0; $iterator < $tableSize; ++$iterator) { |
||
| 113 | $temp = 0; |
||
| 114 | $a = ($iterator << ($this->bitLength - 8)); |
||
| 115 | for ($j = 0; $j < 8; ++$j) { |
||
| 116 | if ((($temp ^ $a) & $highBit) !== 0) { |
||
| 117 | $temp = (($temp << 1) ^ $this->poly); |
||
| 118 | } else { |
||
| 119 | $temp <<= 1; |
||
| 120 | } |
||
| 121 | $a <<= 1; |
||
| 122 | } |
||
| 123 | $table[$iterator] = $temp & $mask; |
||
| 124 | } |
||
| 125 | |||
| 126 | return $table; |
||
| 127 | } |
||
| 128 | |||
| 129 | protected function binaryReverse(int $binaryInput, int $bitlen): int |
||
| 130 | { |
||
| 131 | $cloneBits = $binaryInput; |
||
| 132 | $binaryInput = 0; |
||
| 133 | $count = 0; |
||
| 134 | |||
| 135 | while ($count < $bitlen) { |
||
| 136 | ++$count; |
||
| 137 | $binaryInput <<= 1; |
||
| 138 | $binaryInput |= ($cloneBits & 0x1); |
||
| 139 | $cloneBits >>= 1; |
||
| 140 | } |
||
| 141 | |||
| 142 | return $binaryInput; |
||
| 143 | } |
||
| 144 | } |
||
| 145 |