Completed
Push — master ( 693e1e...7ea7b3 )
by smiley
03:06
created

Polynomial::glog()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class Polynomial
4
 *
5
 * @filesource   Polynomial.php
6
 * @created      25.11.2015
7
 * @package      chillerlan\QRCode\Helpers
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2015 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\QRCode\Helpers;
14
15
use chillerlan\QRCode\QRCodeException;
16
17
/**
18
 * @link http://www.thonky.com/qr-code-tutorial/error-correction-coding
19
 */
20
class Polynomial{
21
22
	/**
23
	 * @link http://www.thonky.com/qr-code-tutorial/log-antilog-table
24
	 */
25
	const table = [
26
		[  1,   0], [  2,   0], [  4,   1], [  8,  25], [ 16,   2], [ 32,  50], [ 64,  26], [128, 198],
27
		[ 29,   3], [ 58, 223], [116,  51], [232, 238], [205,  27], [135, 104], [ 19, 199], [ 38,  75],
28
		[ 76,   4], [152, 100], [ 45, 224], [ 90,  14], [180,  52], [117, 141], [234, 239], [201, 129],
29
		[143,  28], [  3, 193], [  6, 105], [ 12, 248], [ 24, 200], [ 48,   8], [ 96,  76], [192, 113],
30
		[157,   5], [ 39, 138], [ 78, 101], [156,  47], [ 37, 225], [ 74,  36], [148,  15], [ 53,  33],
31
		[106,  53], [212, 147], [181, 142], [119, 218], [238, 240], [193,  18], [159, 130], [ 35,  69],
32
		[ 70,  29], [140, 181], [  5, 194], [ 10, 125], [ 20, 106], [ 40,  39], [ 80, 249], [160, 185],
33
		[ 93, 201], [186, 154], [105,   9], [210, 120], [185,  77], [111, 228], [222, 114], [161, 166],
34
		[ 95,   6], [190, 191], [ 97, 139], [194,  98], [153, 102], [ 47, 221], [ 94,  48], [188, 253],
35
		[101, 226], [202, 152], [137,  37], [ 15, 179], [ 30,  16], [ 60, 145], [120,  34], [240, 136],
36
		[253,  54], [231, 208], [211, 148], [187, 206], [107, 143], [214, 150], [177, 219], [127, 189],
37
		[254, 241], [225, 210], [223,  19], [163,  92], [ 91, 131], [182,  56], [113,  70], [226,  64],
38
		[217,  30], [175,  66], [ 67, 182], [134, 163], [ 17, 195], [ 34,  72], [ 68, 126], [136, 110],
39
		[ 13, 107], [ 26,  58], [ 52,  40], [104,  84], [208, 250], [189, 133], [103, 186], [206,  61],
40
		[129, 202], [ 31,  94], [ 62, 155], [124, 159], [248,  10], [237,  21], [199, 121], [147,  43],
41
		[ 59,  78], [118, 212], [236, 229], [197, 172], [151, 115], [ 51, 243], [102, 167], [204,  87],
42
		[133,   7], [ 23, 112], [ 46, 192], [ 92, 247], [184, 140], [109, 128], [218,  99], [169,  13],
43
		[ 79, 103], [158,  74], [ 33, 222], [ 66, 237], [132,  49], [ 21, 197], [ 42, 254], [ 84,  24],
44
		[168, 227], [ 77, 165], [154, 153], [ 41, 119], [ 82,  38], [164, 184], [ 85, 180], [170, 124],
45
		[ 73,  17], [146,  68], [ 57, 146], [114, 217], [228,  35], [213,  32], [183, 137], [115,  46],
46
		[230,  55], [209,  63], [191, 209], [ 99,  91], [198, 149], [145, 188], [ 63, 207], [126, 205],
47
		[252, 144], [229, 135], [215, 151], [179, 178], [123, 220], [246, 252], [241, 190], [255,  97],
48
		[227, 242], [219,  86], [171, 211], [ 75, 171], [150,  20], [ 49,  42], [ 98,  93], [196, 158],
49
		[149, 132], [ 55,  60], [110,  57], [220,  83], [165,  71], [ 87, 109], [174,  65], [ 65, 162],
50
		[130,  31], [ 25,  45], [ 50,  67], [100, 216], [200, 183], [141, 123], [  7, 164], [ 14, 118],
51
		[ 28, 196], [ 56,  23], [112,  73], [224, 236], [221, 127], [167,  12], [ 83, 111], [166, 246],
52
		[ 81, 108], [162, 161], [ 89,  59], [178,  82], [121,  41], [242, 157], [249,  85], [239, 170],
53
		[195, 251], [155,  96], [ 43, 134], [ 86, 177], [172, 187], [ 69, 204], [138,  62], [  9,  90],
54
		[ 18, 203], [ 36,  89], [ 72,  95], [144, 176], [ 61, 156], [122, 169], [244, 160], [245,  81],
55
		[247,  11], [243, 245], [251,  22], [235, 235], [203, 122], [139, 117], [ 11,  44], [ 22, 215],
56
		[ 44,  79], [ 88, 174], [176, 213], [125, 233], [250, 230], [233, 231], [207, 173], [131, 232],
57
		[ 27, 116], [ 54, 214], [108, 244], [216, 234], [173, 168], [ 71,  80], [142,  88], [  1, 175],
58
	];
59
60
	/**
61
	 * @var array
62
	 */
63
	protected $num = [];
64
65
	/**
66
	 * Polynomial constructor.
67
	 *
68
	 * @param array $num
69
	 * @param int   $shift
70
	 */
71
	public function __construct(array $num = [1], int $shift = 0){
72
		$this->setNum($num, $shift);
73
	}
74
75
	/**
76
	 * @return array
77
	 */
78
	public function getNum():array {
79
		return $this->num;
80
	}
81
82
	/**
83
	 * @param array $num
84
	 * @param int   $shift
85
	 *
86
	 * @return \chillerlan\QRCode\Helpers\Polynomial
87
	 */
88
	public function setNum(array $num, int $shift = 0):Polynomial {
89
		$offset = 0;
90
		$numCount = count($num);
91
92
		while($offset < $numCount && $num[$offset] === 0){
93
			$offset++;
94
		}
95
96
		$this->num = array_fill(0, $numCount - $offset + $shift, 0);
97
98
		for($i = 0; $i < $numCount - $offset; $i++){
99
			$this->num[$i] = $num[$i + $offset];
100
		}
101
102
		return $this;
103
	}
104
105
	/**
106
	 * @param array $e
107
	 *
108
	 * @return \chillerlan\QRCode\Helpers\Polynomial
109
	 */
110
	public function multiply(array $e):Polynomial {
111
		$n = array_fill(0, count($this->num) + count($e) - 1, 0);
112
113
		foreach($this->num as $i => $vi){
114
			$vi = $this->glog($vi);
115
116
			foreach($e as $j => $vj){
117
				$n[$i + $j] ^= $this->gexp($vi + $this->glog($vj));
118
			}
119
120
		}
121
122
		$this->setNum($n);
123
124
		return $this;
125
	}
126
127
	/**
128
	 * @param array $e
129
	 *
130
	 * @return \chillerlan\QRCode\Helpers\Polynomial
131
	 */
132
	public function mod(array $e):Polynomial{
133
		$n = $this->num;
134
135
		if(count($n) - count($e) < 0){
136
			return $this;
137
		}
138
139
		$ratio = $this->glog($n[0]) - $this->glog($e[0]);
140
141
		foreach($e as $i => $v){
142
			$n[$i] ^= $this->gexp($this->glog($v) + $ratio);
143
		}
144
145
		$this->setNum($n)->mod($e);
146
147
		return $this;
148
	}
149
150
	/**
151
	 * @param int $n
152
	 *
153
	 * @return int
154
	 * @throws \chillerlan\QRCode\QRCodeException
155
	 */
156
	public function glog(int $n):int {
157
158
		if($n < 1){
159
			throw new QRCodeException('log('.$n.')');
160
		}
161
162
		return Polynomial::table[$n][1];
163
	}
164
165
	/**
166
	 * @param int $n
167
	 *
168
	 * @return int
169
	 */
170
	public function gexp(int $n):int {
171
172
		if($n < 0){
173
			$n += 255;
174
		}
175
		elseif($n >= 256){
176
			$n -= 255;
177
		}
178
179
		return Polynomial::table[$n][0];
180
	}
181
182
}
183