Completed
Push — master ( 1a2d4b...99084f )
by smiley
03:12
created

Polynomial::setNum()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
rs 9.2
cc 4
eloc 11
nc 4
nop 2
1
<?php
2
/**
3
 * Class Polynomial
4
 *
5
 * @filesource   Polynomial.php
6
 * @created      25.11.2015
7
 * @package      chillerlan\QRCode
8
 * @author       Smiley <[email protected]>
9
 * @copyright    2015 Smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\QRCode;
14
15
/**
16
 *
17
 */
18
class Polynomial{
19
20
	/**
21
	 * @var array
22
	 */
23
	public $num = [];
24
25
	/**
26
	 * @var array
27
	 */
28
	protected $EXP_TABLE = [];
29
30
	/**
31
	 * @var array
32
	 */
33
	protected $LOG_TABLE = [];
34
35
	/**
36
	 * Polynomial constructor.
37
	 *
38
	 * @param array $num
39
	 * @param int   $shift
40
	 */
41
	public function __construct(array $num = [1], $shift = 0){
42
		$this->setNum($num, $shift)->setTables();
43
	}
44
45
	/**
46
	 * @param array $num
47
	 * @param int   $shift
48
	 *
49
	 * @return $this
50
	 */
51
	public function setNum(array $num, $shift = 0){
52
		$offset = 0;
53
		$numCount = count($num);
54
55
		while($offset < $numCount && $num[$offset] === 0){
56
			$offset++;
57
		}
58
59
		$this->num = array_fill(0, $numCount - $offset + $shift, 0);
60
61
		$i = 0;
62
		while($i < $numCount - $offset){
63
			$this->num[$i] = $num[$i + $offset];
64
			$i++;
65
		}
66
67
		return $this;
68
	}
69
70
	/**
71
	 *
72
	 */
73
	protected function setTables(){
74
		$this->EXP_TABLE = $this->LOG_TABLE = array_fill(0, 256, 0);
75
76
		$i = 0;
77
		while($i < 8){
78
			$this->EXP_TABLE[$i] = 1 << $i;
79
			$i++;
80
		}
81
82
		$i = 8;
83
		while($i < 256){
84
			$this->EXP_TABLE[$i] = $this->EXP_TABLE[$i - 4] ^ $this->EXP_TABLE[$i - 5] ^ $this->EXP_TABLE[$i - 6] ^ $this->EXP_TABLE[$i - 8];
85
			$i++;
86
		}
87
88
		$i = 0;
89
		while($i < 255){
90
			$this->LOG_TABLE[$this->EXP_TABLE[$i]] = $i;
91
			$i++;
92
		}
93
94
	}
95
96
	/**
97
	 * @param array $e
98
	 */
99
	public function multiply(array $e){
100
		$n = array_fill(0, count($this->num) + count($e) - 1, 0);
101
102
		foreach($this->num as $i => &$vi){
103
			foreach($e as $j => &$vj){
104
				$n[$i + $j] ^= $this->gexp($this->glog($vi) + $this->glog($vj));
105
			}
106
		}
107
108
		$this->setNum($n);
109
	}
110
111
	/**
112
	 * @param array $e
113
	 */
114
	public function mod(array $e){
115
		$n = $this->num;
116
117
		if(count($n) - count($e) < 0){
118
			return;
119
		}
120
121
		$ratio = $this->glog($n[0]) - $this->glog($e[0]);
122
		foreach($e as $i => &$v){
123
			$n[$i] ^= $this->gexp($this->glog($v) + $ratio);
124
		}
125
126
		$this->setNum($n)->mod($e);
127
	}
128
129
	/**
130
	 * @param int $n
131
	 *
132
	 * @return int
133
	 * @throws \chillerlan\QRCode\QRCodeException
134
	 */
135
	public function glog($n){
136
137
		if($n < 1){
138
			throw new QRCodeException('log('.$n.')');
139
		}
140
141
		return $this->LOG_TABLE[$n];
142
	}
143
144
	/**
145
	 * @param int $n
146
	 *
147
	 * @return int
148
	 */
149
	public function gexp($n){
150
151
		if($n < 0){
152
			$n += 255;
153
		}
154
		elseif($n >= 256){
155
			$n -= 255;
156
		}
157
158
		return $this->EXP_TABLE[$n];
159
	}
160
161
}
162