Completed
Push — master ( ecedd9...16e889 )
by smiley
02:37
created

Util::getBCHT()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
1
<?php
2
/**
3
 * Class Util
4
 *
5
 * @filesource   Util.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 Util{
19
20
	/**
21
	 * @param string $string
22
	 *
23
	 * @return bool
24
	 */
25
	public static function isNumber(string $string):bool {
26
		$len = strlen($string);
27
28
		for($i = 0; $i < $len; $i++){
29
			$chr = ord($string[$i]);
30
31
			if(!(ord('0') <= $chr && $chr <= ord('9'))){
32
				return false;
33
			}
34
		}
35
36
		return true;
37
	}
38
39
	/**
40
	 * @param string $string
41
	 *
42
	 * @return bool
43
	 */
44
	public static function isAlphaNum(string $string):bool {
45
		$len = strlen($string);
46
47
		for($i = 0; $i < $len; $i++){
48
			$chr = ord($string[$i]);
49
50
			if(
51
				  !(ord('0') <= $chr && $chr <= ord('9'))
52
			   && !(ord('A') <= $chr && $chr <= ord('Z'))
53
			   && strpos(' $%*+-./:', $string[$i]) === false
54
			){
55
				return false;
56
			}
57
		}
58
59
		return true;
60
	}
61
62
	/**
63
	 * @param string $string
64
	 *
65
	 * @return bool
66
	 */
67
	public static function isKanji(string $string):bool {
68
69
		if(empty($string)){
70
			return false;
71
		}
72
73
		$i = 0;
74
		$length = strlen($string);
75
76
		while($i + 1 < $length){
77
			$c = ((0xff&ord($string[$i])) << 8)|(0xff&ord($string[$i + 1]));
78
79
			if(!($c >= 0x8140 && $c <= 0x9FFC) && !($c >= 0xE040 && $c <= 0xEBBF)){
80
				return false;
81
			}
82
83
			$i += 2;
84
		}
85
86
		return !($i < $length);
87
	}
88
89
	/**
90
	 * @param int $data
91
	 *
92
	 * @return int
93
	 */
94
	public static function getBCHTypeInfo(int $data):int {
95
		return (($data << 10)|self::getBCHT($data, 10, QRConst::G15))^QRConst::G15_MASK;
96
	}
97
98
	/**
99
	 * @param int $data
100
	 *
101
	 * @return int
102
	 */
103
	public static function getBCHTypeNumber(int $data):int{
104
		return ($data << 12)|self::getBCHT($data, 12, QRConst::G18);
105
	}
106
107
	/**
108
	 * @param int $data
109
	 * @param int $bits
110
	 * @param int $mask
111
	 *
112
	 * @return int
113
	 */
114
	protected static function getBCHT(int $data, int $bits, int $mask):int {
115
		$digit = $data << $bits;
116
117
		while(self::getBCHDigit($digit) - self::getBCHDigit($mask) >= 0){
118
			$digit ^= ($mask << (self::getBCHDigit($digit) - self::getBCHDigit($mask)));
119
		}
120
121
		return $digit;
122
	}
123
124
	/**
125
	 * @param int $data
126
	 *
127
	 * @return int
128
	 */
129
	public static function getBCHDigit(int $data):int {
130
		$digit = 0;
131
132
		while($data !== 0){
133
			$digit++;
134
			$data >>= 1;
135
		}
136
137
		return $digit;
138
	}
139
140
	/**
141
	 * @param int $typeNumber
142
	 * @param int $errorCorrectLevel
143
	 *
144
	 * @return array
145
	 * @throws \chillerlan\QRCode\QRCodeException
146
	 */
147
	public static function getRSBlocks(int $typeNumber, int $errorCorrectLevel):array {
148
149
		if(!array_key_exists($errorCorrectLevel, QRConst::RSBLOCK)){
150
			throw new QRCodeException('$typeNumber: '.$typeNumber.' / $errorCorrectLevel: '.$errorCorrectLevel);
151
		}
152
153
		$rsBlock = QRConst::BLOCK_TABLE[($typeNumber - 1) * 4 + QRConst::RSBLOCK[$errorCorrectLevel]];
154
		$list = [];
155
		$length = count($rsBlock) / 3;
156
157
		for($i = 0; $i < $length; $i++){
158
			for($j = 0; $j < $rsBlock[$i * 3 + 0]; $j++){
159
				$list[] = [$rsBlock[$i * 3 + 1], $rsBlock[$i * 3 + 2]];
160
			}
161
		}
162
163
		return $list;
164
	}
165
166
	/**
167
	 * @param int $typeNumber
168
	 * @param int $mode
169
	 * @param int $errorCorrectLevel
170
	 *
171
	 * @return int
172
	 * @throws \chillerlan\QRCode\QRCodeException
173
	 */
174
	public static function getMaxLength(int $typeNumber, int $mode, int $errorCorrectLevel):int {
175
176
		if(!array_key_exists($errorCorrectLevel, QRConst::RSBLOCK)){
177
			throw new QRCodeException('Invalid error correct level: '.$errorCorrectLevel);
178
		}
179
180
		if(!array_key_exists($mode, QRConst::MODE)){
181
			throw new QRCodeException('Invalid mode: '.$mode);
182
		}
183
184
		return QRConst::MAX_LENGTH[$typeNumber - 1][QRConst::RSBLOCK[$errorCorrectLevel]][QRConst::MODE[$mode]];
185
	}
186
187
}
188