1<?php 2 3// namespace changed for DokuWiki plugin 4namespace dokuwiki\plugin\twofactorgoogleauth; 5 6/** 7 * 8 * Copyright (c) 2016-2018 Kreative Software. 9 * Stripped down version inspired by Donald Becker, 2019 10 * Minimal SVG builder, composer support by Andreas Gohr, 2022 11 * 12 * Permission is hereby granted, free of charge, to any person obtaining a copy 13 * of this software and associated documentation files (the "Software"), to deal 14 * in the Software without restriction, including without limitation the rights 15 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 * copies of the Software, and to permit persons to whom the Software is 17 * furnished to do so, subject to the following conditions: 18 * The above copyright notice and this permission notice shall be included in 19 * all copies or substantial portions of the Software. 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 * @author Kreative Software 29 * @link https://github.com/kreativekorp/barcode 30 * @author Donald Becker 31 * @link https://github.com/psyon/php-qrcode 32 * @license MIT 33 */ 34class QRCode 35{ 36 protected $data; 37 protected $options; 38 39 /** 40 * @param string $data 41 * @param array $options 42 */ 43 public function __construct($data, $options = []) 44 { 45 $defaults = [ 46 's' => 'qrl' 47 ]; 48 if (!is_array($options)) $options = []; 49 50 $this->data = $data; 51 $this->options = array_merge($defaults, $options); 52 } 53 54 /** 55 * Convenience method to quickly generate an SVG 56 * 57 * @param string $data 58 * @param array $options 59 * @return string 60 */ 61 static public function svg($data, $options = []) 62 { 63 return (new QRCode($data, $options))->createSVG(); 64 } 65 66 /** 67 * Create a SVG ready to be inlined 68 * 69 * @return string 70 */ 71 public function createSVG() 72 { 73 $code = $this->dispatch_encode($this->data, $this->options); 74 $svg = sprintf('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d %d">', $code['s'][0], $code['s'][1]); 75 foreach ($code['b'] as $y => $row) { 76 foreach ($row as $x => $val) { 77 if ($val) { 78 $svg .= sprintf('<rect x="%d" y="%d" width="1" height="1" />', $x, $y); 79 } 80 } 81 } 82 $svg .= '</svg>'; 83 84 return $svg; 85 } 86 87 /* - - - - DISPATCH - - - - */ 88 89 protected function dispatch_encode($data, $options) 90 { 91 switch (strtolower(preg_replace('/[^A-Za-z0-9]/', '', $options['s']))) { 92 case 'qrl': 93 return $this->qr_encode($data, 0); 94 case 'qrm': 95 return $this->qr_encode($data, 1); 96 case 'qrq': 97 return $this->qr_encode($data, 2); 98 case 'qrh': 99 return $this->qr_encode($data, 3); 100 default: 101 return $this->qr_encode($data, 0); 102 } 103 } 104 105 106 // region QR Encoder 107 108 protected function qr_encode($data, $ecl) 109 { 110 list($mode, $vers, $ec, $data) = $this->qr_encode_data($data, $ecl); 111 $data = $this->qr_encode_ec($data, $ec, $vers); 112 list($size, $mtx) = $this->qr_create_matrix($vers, $data); 113 list($mask, $mtx) = $this->qr_apply_best_mask($mtx, $size); 114 $mtx = $this->qr_finalize_matrix($mtx, $size, $ecl, $mask, $vers); 115 return array( 116 'g' => 'm', 117 'q' => array(4, 4, 4, 4), 118 's' => array($size, $size), 119 'b' => $mtx 120 ); 121 } 122 123 protected function qr_encode_data($data, $ecl) 124 { 125 $mode = $this->qr_detect_mode($data); 126 $version = $this->qr_detect_version($data, $mode, $ecl); 127 $version_group = (($version < 10) ? 0 : (($version < 27) ? 1 : 2)); 128 $ec_params = $this->qr_ec_params[($version - 1) * 4 + $ecl]; 129 /* Don't cut off mid-character if exceeding capacity. */ 130 $max_chars = $this->qr_capacity[$version - 1][$ecl][$mode]; 131 if ($mode == 3) $max_chars <<= 1; 132 $data = substr($data, 0, $max_chars); 133 /* Convert from character level to bit level. */ 134 switch ($mode) { 135 case 0: 136 $code = $this->qr_encode_numeric($data, $version_group); 137 break; 138 case 1: 139 $code = $this->qr_encode_alphanumeric($data, $version_group); 140 break; 141 case 2: 142 $code = $this->qr_encode_binary($data, $version_group); 143 break; 144 case 3: 145 $code = $this->qr_encode_kanji($data, $version_group); 146 break; 147 } 148 for ($i = 0; $i < 4; $i++) $code[] = 0; 149 while (count($code) % 8) $code[] = 0; 150 /* Convert from bit level to byte level. */ 151 $data = array(); 152 for ($i = 0, $n = count($code); $i < $n; $i += 8) { 153 $byte = 0; 154 if ($code[$i + 0]) $byte |= 0x80; 155 if ($code[$i + 1]) $byte |= 0x40; 156 if ($code[$i + 2]) $byte |= 0x20; 157 if ($code[$i + 3]) $byte |= 0x10; 158 if ($code[$i + 4]) $byte |= 0x08; 159 if ($code[$i + 5]) $byte |= 0x04; 160 if ($code[$i + 6]) $byte |= 0x02; 161 if ($code[$i + 7]) $byte |= 0x01; 162 $data[] = $byte; 163 } 164 for ( 165 $i = count($data), $a = 1, $n = $ec_params[0]; 166 $i < $n; $i++, $a ^= 1 167 ) { 168 $data[] = $a ? 236 : 17; 169 } 170 /* Return. */ 171 return array($mode, $version, $ec_params, $data); 172 } 173 174 protected function qr_detect_mode($data) 175 { 176 $numeric = '/^[0-9]*$/'; 177 $alphanumeric = '/^[0-9A-Z .\/:$%*+-]*$/'; 178 $kanji = '/^([\x81-\x9F\xE0-\xEA][\x40-\xFC]|[\xEB][\x40-\xBF])*$/'; 179 if (preg_match($numeric, $data)) return 0; 180 if (preg_match($alphanumeric, $data)) return 1; 181 if (preg_match($kanji, $data)) return 3; 182 return 2; 183 } 184 185 protected function qr_detect_version($data, $mode, $ecl) 186 { 187 $length = strlen($data); 188 if ($mode == 3) $length >>= 1; 189 for ($v = 0; $v < 40; $v++) { 190 if ($length <= $this->qr_capacity[$v][$ecl][$mode]) { 191 return $v + 1; 192 } 193 } 194 return 40; 195 } 196 197 protected function qr_encode_numeric($data, $version_group) 198 { 199 $code = array(0, 0, 0, 1); 200 $length = strlen($data); 201 switch ($version_group) { 202 case 2: /* 27 - 40 */ 203 $code[] = $length & 0x2000; 204 $code[] = $length & 0x1000; 205 case 1: /* 10 - 26 */ 206 $code[] = $length & 0x0800; 207 $code[] = $length & 0x0400; 208 case 0: /* 1 - 9 */ 209 $code[] = $length & 0x0200; 210 $code[] = $length & 0x0100; 211 $code[] = $length & 0x0080; 212 $code[] = $length & 0x0040; 213 $code[] = $length & 0x0020; 214 $code[] = $length & 0x0010; 215 $code[] = $length & 0x0008; 216 $code[] = $length & 0x0004; 217 $code[] = $length & 0x0002; 218 $code[] = $length & 0x0001; 219 } 220 for ($i = 0; $i < $length; $i += 3) { 221 $group = substr($data, $i, 3); 222 switch (strlen($group)) { 223 case 3: 224 $code[] = $group & 0x200; 225 $code[] = $group & 0x100; 226 $code[] = $group & 0x080; 227 case 2: 228 $code[] = $group & 0x040; 229 $code[] = $group & 0x020; 230 $code[] = $group & 0x010; 231 case 1: 232 $code[] = $group & 0x008; 233 $code[] = $group & 0x004; 234 $code[] = $group & 0x002; 235 $code[] = $group & 0x001; 236 } 237 } 238 return $code; 239 } 240 241 protected function qr_encode_alphanumeric($data, $version_group) 242 { 243 $alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:'; 244 $code = array(0, 0, 1, 0); 245 $length = strlen($data); 246 switch ($version_group) { 247 case 2: /* 27 - 40 */ 248 $code[] = $length & 0x1000; 249 $code[] = $length & 0x0800; 250 case 1: /* 10 - 26 */ 251 $code[] = $length & 0x0400; 252 $code[] = $length & 0x0200; 253 case 0: /* 1 - 9 */ 254 $code[] = $length & 0x0100; 255 $code[] = $length & 0x0080; 256 $code[] = $length & 0x0040; 257 $code[] = $length & 0x0020; 258 $code[] = $length & 0x0010; 259 $code[] = $length & 0x0008; 260 $code[] = $length & 0x0004; 261 $code[] = $length & 0x0002; 262 $code[] = $length & 0x0001; 263 } 264 for ($i = 0; $i < $length; $i += 2) { 265 $group = substr($data, $i, 2); 266 if (strlen($group) > 1) { 267 $c1 = strpos($alphabet, substr($group, 0, 1)); 268 $c2 = strpos($alphabet, substr($group, 1, 1)); 269 $ch = $c1 * 45 + $c2; 270 $code[] = $ch & 0x400; 271 $code[] = $ch & 0x200; 272 $code[] = $ch & 0x100; 273 $code[] = $ch & 0x080; 274 $code[] = $ch & 0x040; 275 $code[] = $ch & 0x020; 276 $code[] = $ch & 0x010; 277 $code[] = $ch & 0x008; 278 $code[] = $ch & 0x004; 279 $code[] = $ch & 0x002; 280 $code[] = $ch & 0x001; 281 } else { 282 $ch = strpos($alphabet, $group); 283 $code[] = $ch & 0x020; 284 $code[] = $ch & 0x010; 285 $code[] = $ch & 0x008; 286 $code[] = $ch & 0x004; 287 $code[] = $ch & 0x002; 288 $code[] = $ch & 0x001; 289 } 290 } 291 return $code; 292 } 293 294 protected function qr_encode_binary($data, $version_group) 295 { 296 $code = array(0, 1, 0, 0); 297 $length = strlen($data); 298 switch ($version_group) { 299 case 2: /* 27 - 40 */ 300 case 1: /* 10 - 26 */ 301 $code[] = $length & 0x8000; 302 $code[] = $length & 0x4000; 303 $code[] = $length & 0x2000; 304 $code[] = $length & 0x1000; 305 $code[] = $length & 0x0800; 306 $code[] = $length & 0x0400; 307 $code[] = $length & 0x0200; 308 $code[] = $length & 0x0100; 309 case 0: /* 1 - 9 */ 310 $code[] = $length & 0x0080; 311 $code[] = $length & 0x0040; 312 $code[] = $length & 0x0020; 313 $code[] = $length & 0x0010; 314 $code[] = $length & 0x0008; 315 $code[] = $length & 0x0004; 316 $code[] = $length & 0x0002; 317 $code[] = $length & 0x0001; 318 } 319 for ($i = 0; $i < $length; $i++) { 320 $ch = ord(substr($data, $i, 1)); 321 $code[] = $ch & 0x80; 322 $code[] = $ch & 0x40; 323 $code[] = $ch & 0x20; 324 $code[] = $ch & 0x10; 325 $code[] = $ch & 0x08; 326 $code[] = $ch & 0x04; 327 $code[] = $ch & 0x02; 328 $code[] = $ch & 0x01; 329 } 330 return $code; 331 } 332 333 protected function qr_encode_kanji($data, $version_group) 334 { 335 $code = array(1, 0, 0, 0); 336 $length = strlen($data); 337 switch ($version_group) { 338 case 2: /* 27 - 40 */ 339 $code[] = $length & 0x1000; 340 $code[] = $length & 0x0800; 341 case 1: /* 10 - 26 */ 342 $code[] = $length & 0x0400; 343 $code[] = $length & 0x0200; 344 case 0: /* 1 - 9 */ 345 $code[] = $length & 0x0100; 346 $code[] = $length & 0x0080; 347 $code[] = $length & 0x0040; 348 $code[] = $length & 0x0020; 349 $code[] = $length & 0x0010; 350 $code[] = $length & 0x0008; 351 $code[] = $length & 0x0004; 352 $code[] = $length & 0x0002; 353 } 354 for ($i = 0; $i < $length; $i += 2) { 355 $group = substr($data, $i, 2); 356 $c1 = ord(substr($group, 0, 1)); 357 $c2 = ord(substr($group, 1, 1)); 358 if ($c1 >= 0x81 && $c1 <= 0x9F && $c2 >= 0x40 && $c2 <= 0xFC) { 359 $ch = ($c1 - 0x81) * 0xC0 + ($c2 - 0x40); 360 } else if ( 361 ($c1 >= 0xE0 && $c1 <= 0xEA && $c2 >= 0x40 && $c2 <= 0xFC) || 362 ($c1 == 0xEB && $c2 >= 0x40 && $c2 <= 0xBF) 363 ) { 364 $ch = ($c1 - 0xC1) * 0xC0 + ($c2 - 0x40); 365 } else { 366 $ch = 0; 367 } 368 $code[] = $ch & 0x1000; 369 $code[] = $ch & 0x0800; 370 $code[] = $ch & 0x0400; 371 $code[] = $ch & 0x0200; 372 $code[] = $ch & 0x0100; 373 $code[] = $ch & 0x0080; 374 $code[] = $ch & 0x0040; 375 $code[] = $ch & 0x0020; 376 $code[] = $ch & 0x0010; 377 $code[] = $ch & 0x0008; 378 $code[] = $ch & 0x0004; 379 $code[] = $ch & 0x0002; 380 $code[] = $ch & 0x0001; 381 } 382 return $code; 383 } 384 385 protected function qr_encode_ec($data, $ec_params, $version) 386 { 387 $blocks = $this->qr_ec_split($data, $ec_params); 388 $ec_blocks = array(); 389 for ($i = 0, $n = count($blocks); $i < $n; $i++) { 390 $ec_blocks[] = $this->qr_ec_divide($blocks[$i], $ec_params); 391 } 392 $data = $this->qr_ec_interleave($blocks); 393 $ec_data = $this->qr_ec_interleave($ec_blocks); 394 $code = array(); 395 foreach ($data as $ch) { 396 $code[] = $ch & 0x80; 397 $code[] = $ch & 0x40; 398 $code[] = $ch & 0x20; 399 $code[] = $ch & 0x10; 400 $code[] = $ch & 0x08; 401 $code[] = $ch & 0x04; 402 $code[] = $ch & 0x02; 403 $code[] = $ch & 0x01; 404 } 405 foreach ($ec_data as $ch) { 406 $code[] = $ch & 0x80; 407 $code[] = $ch & 0x40; 408 $code[] = $ch & 0x20; 409 $code[] = $ch & 0x10; 410 $code[] = $ch & 0x08; 411 $code[] = $ch & 0x04; 412 $code[] = $ch & 0x02; 413 $code[] = $ch & 0x01; 414 } 415 for ($n = $this->qr_remainder_bits[$version - 1]; $n > 0; $n--) { 416 $code[] = 0; 417 } 418 return $code; 419 } 420 421 protected function qr_ec_split($data, $ec_params) 422 { 423 $blocks = array(); 424 $offset = 0; 425 for ($i = $ec_params[2], $length = $ec_params[3]; $i > 0; $i--) { 426 $blocks[] = array_slice($data, $offset, $length); 427 $offset += $length; 428 } 429 for ($i = $ec_params[4], $length = $ec_params[5]; $i > 0; $i--) { 430 $blocks[] = array_slice($data, $offset, $length); 431 $offset += $length; 432 } 433 return $blocks; 434 } 435 436 protected function qr_ec_divide($data, $ec_params) 437 { 438 $num_data = count($data); 439 $num_error = $ec_params[1]; 440 $generator = $this->qr_ec_polynomials[$num_error]; 441 $message = $data; 442 for ($i = 0; $i < $num_error; $i++) { 443 $message[] = 0; 444 } 445 for ($i = 0; $i < $num_data; $i++) { 446 if ($message[$i]) { 447 $leadterm = $this->qr_log[$message[$i]]; 448 for ($j = 0; $j <= $num_error; $j++) { 449 $term = ($generator[$j] + $leadterm) % 255; 450 $message[$i + $j] ^= $this->qr_exp[$term]; 451 } 452 } 453 } 454 return array_slice($message, $num_data, $num_error); 455 } 456 457 protected function qr_ec_interleave($blocks) 458 { 459 $data = array(); 460 $num_blocks = count($blocks); 461 for ($offset = 0; true; $offset++) { 462 $break = true; 463 for ($i = 0; $i < $num_blocks; $i++) { 464 if (isset($blocks[$i][$offset])) { 465 $data[] = $blocks[$i][$offset]; 466 $break = false; 467 } 468 } 469 if ($break) break; 470 } 471 return $data; 472 } 473 474 protected function qr_create_matrix($version, $data) 475 { 476 $size = $version * 4 + 17; 477 $matrix = array(); 478 for ($i = 0; $i < $size; $i++) { 479 $row = array(); 480 for ($j = 0; $j < $size; $j++) { 481 $row[] = 0; 482 } 483 $matrix[] = $row; 484 } 485 /* Finder patterns. */ 486 for ($i = 0; $i < 8; $i++) { 487 for ($j = 0; $j < 8; $j++) { 488 $m = (($i == 7 || $j == 7) ? 2 : 489 (($i == 0 || $j == 0 || $i == 6 || $j == 6) ? 3 : 490 (($i == 1 || $j == 1 || $i == 5 || $j == 5) ? 2 : 3))); 491 $matrix[$i][$j] = $m; 492 $matrix[$size - $i - 1][$j] = $m; 493 $matrix[$i][$size - $j - 1] = $m; 494 } 495 } 496 /* Alignment patterns. */ 497 if ($version >= 2) { 498 $alignment = $this->qr_alignment_patterns[$version - 2]; 499 foreach ($alignment as $i) { 500 foreach ($alignment as $j) { 501 if (!$matrix[$i][$j]) { 502 for ($ii = -2; $ii <= 2; $ii++) { 503 for ($jj = -2; $jj <= 2; $jj++) { 504 $m = (max(abs($ii), abs($jj)) & 1) ^ 3; 505 $matrix[$i + $ii][$j + $jj] = $m; 506 } 507 } 508 } 509 } 510 } 511 } 512 /* Timing patterns. */ 513 for ($i = $size - 9; $i >= 8; $i--) { 514 $matrix[$i][6] = ($i & 1) ^ 3; 515 $matrix[6][$i] = ($i & 1) ^ 3; 516 } 517 /* Dark module. Such an ominous name for such an innocuous thing. */ 518 $matrix[$size - 8][8] = 3; 519 /* Format information area. */ 520 for ($i = 0; $i <= 8; $i++) { 521 if (!$matrix[$i][8]) $matrix[$i][8] = 1; 522 if (!$matrix[8][$i]) $matrix[8][$i] = 1; 523 if ($i && !$matrix[$size - $i][8]) $matrix[$size - $i][8] = 1; 524 if ($i && !$matrix[8][$size - $i]) $matrix[8][$size - $i] = 1; 525 } 526 /* Version information area. */ 527 if ($version >= 7) { 528 for ($i = 9; $i < 12; $i++) { 529 for ($j = 0; $j < 6; $j++) { 530 $matrix[$size - $i][$j] = 1; 531 $matrix[$j][$size - $i] = 1; 532 } 533 } 534 } 535 /* Data. */ 536 $col = $size - 1; 537 $row = $size - 1; 538 $dir = -1; 539 $offset = 0; 540 $length = count($data); 541 while ($col > 0 && $offset < $length) { 542 if (!$matrix[$row][$col]) { 543 $matrix[$row][$col] = $data[$offset] ? 5 : 4; 544 $offset++; 545 } 546 if (!$matrix[$row][$col - 1]) { 547 $matrix[$row][$col - 1] = $data[$offset] ? 5 : 4; 548 $offset++; 549 } 550 $row += $dir; 551 if ($row < 0 || $row >= $size) { 552 $dir = -$dir; 553 $row += $dir; 554 $col -= 2; 555 if ($col == 6) $col--; 556 } 557 } 558 return array($size, $matrix); 559 } 560 561 protected function qr_apply_best_mask($matrix, $size) 562 { 563 $best_mask = 0; 564 $best_matrix = $this->qr_apply_mask($matrix, $size, $best_mask); 565 $best_penalty = $this->qr_penalty($best_matrix, $size); 566 for ($test_mask = 1; $test_mask < 8; $test_mask++) { 567 $test_matrix = $this->qr_apply_mask($matrix, $size, $test_mask); 568 $test_penalty = $this->qr_penalty($test_matrix, $size); 569 if ($test_penalty < $best_penalty) { 570 $best_mask = $test_mask; 571 $best_matrix = $test_matrix; 572 $best_penalty = $test_penalty; 573 } 574 } 575 return array($best_mask, $best_matrix); 576 } 577 578 protected function qr_apply_mask($matrix, $size, $mask) 579 { 580 for ($i = 0; $i < $size; $i++) { 581 for ($j = 0; $j < $size; $j++) { 582 if ($matrix[$i][$j] >= 4) { 583 if ($this->qr_mask($mask, $i, $j)) { 584 $matrix[$i][$j] ^= 1; 585 } 586 } 587 } 588 } 589 return $matrix; 590 } 591 592 protected function qr_mask($mask, $r, $c) 593 { 594 switch ($mask) { 595 case 0: 596 return !(($r + $c) % 2); 597 case 1: 598 return !(($r) % 2); 599 case 2: 600 return !(($c) % 3); 601 case 3: 602 return !(($r + $c) % 3); 603 case 4: 604 return !((floor(($r) / 2) + floor(($c) / 3)) % 2); 605 case 5: 606 return !(((($r * $c) % 2) + (($r * $c) % 3))); 607 case 6: 608 return !(((($r * $c) % 2) + (($r * $c) % 3)) % 2); 609 case 7: 610 return !(((($r + $c) % 2) + (($r * $c) % 3)) % 2); 611 } 612 } 613 614 protected function qr_penalty(&$matrix, $size) 615 { 616 $score = $this->qr_penalty_1($matrix, $size); 617 $score += $this->qr_penalty_2($matrix, $size); 618 $score += $this->qr_penalty_3($matrix, $size); 619 $score += $this->qr_penalty_4($matrix, $size); 620 return $score; 621 } 622 623 protected function qr_penalty_1(&$matrix, $size) 624 { 625 $score = 0; 626 for ($i = 0; $i < $size; $i++) { 627 $rowvalue = 0; 628 $rowcount = 0; 629 $colvalue = 0; 630 $colcount = 0; 631 for ($j = 0; $j < $size; $j++) { 632 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0; 633 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0; 634 if ($rv == $rowvalue) { 635 $rowcount++; 636 } else { 637 if ($rowcount >= 5) $score += $rowcount - 2; 638 $rowvalue = $rv; 639 $rowcount = 1; 640 } 641 if ($cv == $colvalue) { 642 $colcount++; 643 } else { 644 if ($colcount >= 5) $score += $colcount - 2; 645 $colvalue = $cv; 646 $colcount = 1; 647 } 648 } 649 if ($rowcount >= 5) $score += $rowcount - 2; 650 if ($colcount >= 5) $score += $colcount - 2; 651 } 652 return $score; 653 } 654 655 protected function qr_penalty_2(&$matrix, $size) 656 { 657 $score = 0; 658 for ($i = 1; $i < $size; $i++) { 659 for ($j = 1; $j < $size; $j++) { 660 $v1 = $matrix[$i - 1][$j - 1]; 661 $v2 = $matrix[$i - 1][$j]; 662 $v3 = $matrix[$i][$j - 1]; 663 $v4 = $matrix[$i][$j]; 664 $v1 = ($v1 == 5 || $v1 == 3) ? 1 : 0; 665 $v2 = ($v2 == 5 || $v2 == 3) ? 1 : 0; 666 $v3 = ($v3 == 5 || $v3 == 3) ? 1 : 0; 667 $v4 = ($v4 == 5 || $v4 == 3) ? 1 : 0; 668 if ($v1 == $v2 && $v2 == $v3 && $v3 == $v4) $score += 3; 669 } 670 } 671 return $score; 672 } 673 674 protected function qr_penalty_3(&$matrix, $size) 675 { 676 $score = 0; 677 for ($i = 0; $i < $size; $i++) { 678 $rowvalue = 0; 679 $colvalue = 0; 680 for ($j = 0; $j < 11; $j++) { 681 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0; 682 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0; 683 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv; 684 $colvalue = (($colvalue << 1) & 0x7FF) | $cv; 685 } 686 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40; 687 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40; 688 for ($j = 11; $j < $size; $j++) { 689 $rv = ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) ? 1 : 0; 690 $cv = ($matrix[$j][$i] == 5 || $matrix[$j][$i] == 3) ? 1 : 0; 691 $rowvalue = (($rowvalue << 1) & 0x7FF) | $rv; 692 $colvalue = (($colvalue << 1) & 0x7FF) | $cv; 693 if ($rowvalue == 0x5D0 || $rowvalue == 0x5D) $score += 40; 694 if ($colvalue == 0x5D0 || $colvalue == 0x5D) $score += 40; 695 } 696 } 697 return $score; 698 } 699 700 protected function qr_penalty_4(&$matrix, $size) 701 { 702 $dark = 0; 703 for ($i = 0; $i < $size; $i++) { 704 for ($j = 0; $j < $size; $j++) { 705 if ($matrix[$i][$j] == 5 || $matrix[$i][$j] == 3) { 706 $dark++; 707 } 708 } 709 } 710 $dark *= 20; 711 $dark /= $size * $size; 712 $a = abs(floor($dark) - 10); 713 $b = abs(ceil($dark) - 10); 714 return min($a, $b) * 10; 715 } 716 717 protected function qr_finalize_matrix( 718 $matrix, $size, $ecl, $mask, $version 719 ) 720 { 721 /* Format Info */ 722 $format = $this->qr_format_info[$ecl * 8 + $mask]; 723 $matrix[8][0] = $format[0]; 724 $matrix[8][1] = $format[1]; 725 $matrix[8][2] = $format[2]; 726 $matrix[8][3] = $format[3]; 727 $matrix[8][4] = $format[4]; 728 $matrix[8][5] = $format[5]; 729 $matrix[8][7] = $format[6]; 730 $matrix[8][8] = $format[7]; 731 $matrix[7][8] = $format[8]; 732 $matrix[5][8] = $format[9]; 733 $matrix[4][8] = $format[10]; 734 $matrix[3][8] = $format[11]; 735 $matrix[2][8] = $format[12]; 736 $matrix[1][8] = $format[13]; 737 $matrix[0][8] = $format[14]; 738 $matrix[$size - 1][8] = $format[0]; 739 $matrix[$size - 2][8] = $format[1]; 740 $matrix[$size - 3][8] = $format[2]; 741 $matrix[$size - 4][8] = $format[3]; 742 $matrix[$size - 5][8] = $format[4]; 743 $matrix[$size - 6][8] = $format[5]; 744 $matrix[$size - 7][8] = $format[6]; 745 $matrix[8][$size - 8] = $format[7]; 746 $matrix[8][$size - 7] = $format[8]; 747 $matrix[8][$size - 6] = $format[9]; 748 $matrix[8][$size - 5] = $format[10]; 749 $matrix[8][$size - 4] = $format[11]; 750 $matrix[8][$size - 3] = $format[12]; 751 $matrix[8][$size - 2] = $format[13]; 752 $matrix[8][$size - 1] = $format[14]; 753 /* Version Info */ 754 if ($version >= 7) { 755 $version = $this->qr_version_info[$version - 7]; 756 for ($i = 0; $i < 18; $i++) { 757 $r = $size - 9 - ($i % 3); 758 $c = 5 - floor($i / 3); 759 $matrix[$r][$c] = $version[$i]; 760 $matrix[$c][$r] = $version[$i]; 761 } 762 } 763 /* Patterns & Data */ 764 for ($i = 0; $i < $size; $i++) { 765 for ($j = 0; $j < $size; $j++) { 766 $matrix[$i][$j] &= 1; 767 } 768 } 769 return $matrix; 770 } 771 772 /* maximum encodable characters = $qr_capacity [ (version - 1) ] */ 773 /* [ (0 for L, 1 for M, 2 for Q, 3 for H) ] */ 774 /* [ (0 for numeric, 1 for alpha, 2 for binary, 3 for kanji) ] */ 775 protected $qr_capacity = [ 776 [[41, 25, 17, 10], [34, 20, 14, 8], 777 [27, 16, 11, 7], [17, 10, 7, 4]], 778 [[77, 47, 32, 20], [63, 38, 26, 16], 779 [48, 29, 20, 12], [34, 20, 14, 8]], 780 [[127, 77, 53, 32], [101, 61, 42, 26], 781 [77, 47, 32, 20], [58, 35, 24, 15]], 782 [[187, 114, 78, 48], [149, 90, 62, 38], 783 [111, 67, 46, 28], [82, 50, 34, 21]], 784 [[255, 154, 106, 65], [202, 122, 84, 52], 785 [144, 87, 60, 37], [106, 64, 44, 27]], 786 [[322, 195, 134, 82], [255, 154, 106, 65], 787 [178, 108, 74, 45], [139, 84, 58, 36]], 788 [[370, 224, 154, 95], [293, 178, 122, 75], 789 [207, 125, 86, 53], [154, 93, 64, 39]], 790 [[461, 279, 192, 118], [365, 221, 152, 93], 791 [259, 157, 108, 66], [202, 122, 84, 52]], 792 [[552, 335, 230, 141], [432, 262, 180, 111], 793 [312, 189, 130, 80], [235, 143, 98, 60]], 794 [[652, 395, 271, 167], [513, 311, 213, 131], 795 [364, 221, 151, 93], [288, 174, 119, 74]], 796 [[772, 468, 321, 198], [604, 366, 251, 155], 797 [427, 259, 177, 109], [331, 200, 137, 85]], 798 [[883, 535, 367, 226], [691, 419, 287, 177], 799 [489, 296, 203, 125], [374, 227, 155, 96]], 800 [[1022, 619, 425, 262], [796, 483, 331, 204], 801 [580, 352, 241, 149], [427, 259, 177, 109]], 802 [[1101, 667, 458, 282], [871, 528, 362, 223], 803 [621, 376, 258, 159], [468, 283, 194, 120]], 804 [[1250, 758, 520, 320], [991, 600, 412, 254], 805 [703, 426, 292, 180], [530, 321, 220, 136]], 806 [[1408, 854, 586, 361], [1082, 656, 450, 277], 807 [775, 470, 322, 198], [602, 365, 250, 154]], 808 [[1548, 938, 644, 397], [1212, 734, 504, 310], 809 [876, 531, 364, 224], [674, 408, 280, 173]], 810 [[1725, 1046, 718, 442], [1346, 816, 560, 345], 811 [948, 574, 394, 243], [746, 452, 310, 191]], 812 [[1903, 1153, 792, 488], [1500, 909, 624, 384], 813 [1063, 644, 442, 272], [813, 493, 338, 208]], 814 [[2061, 1249, 858, 528], [1600, 970, 666, 410], 815 [1159, 702, 482, 297], [919, 557, 382, 235]], 816 [[2232, 1352, 929, 572], [1708, 1035, 711, 438], 817 [1224, 742, 509, 314], [969, 587, 403, 248]], 818 [[2409, 1460, 1003, 618], [1872, 1134, 779, 480], 819 [1358, 823, 565, 348], [1056, 640, 439, 270]], 820 [[2620, 1588, 1091, 672], [2059, 1248, 857, 528], 821 [1468, 890, 611, 376], [1108, 672, 461, 284]], 822 [[2812, 1704, 1171, 721], [2188, 1326, 911, 561], 823 [1588, 963, 661, 407], [1228, 744, 511, 315]], 824 [[3057, 1853, 1273, 784], [2395, 1451, 997, 614], 825 [1718, 1041, 715, 440], [1286, 779, 535, 330]], 826 [[3283, 1990, 1367, 842], [2544, 1542, 1059, 652], 827 [1804, 1094, 751, 462], [1425, 864, 593, 365]], 828 [[3517, 2132, 1465, 902], [2701, 1637, 1125, 692], 829 [1933, 1172, 805, 496], [1501, 910, 625, 385]], 830 [[3669, 2223, 1528, 940], [2857, 1732, 1190, 732], 831 [2085, 1263, 868, 534], [1581, 958, 658, 405]], 832 [[3909, 2369, 1628, 1002], [3035, 1839, 1264, 778], 833 [2181, 1322, 908, 559], [1677, 1016, 698, 430]], 834 [[4158, 2520, 1732, 1066], [3289, 1994, 1370, 843], 835 [2358, 1429, 982, 604], [1782, 1080, 742, 457]], 836 [[4417, 2677, 1840, 1132], [3486, 2113, 1452, 894], 837 [2473, 1499, 1030, 634], [1897, 1150, 790, 486]], 838 [[4686, 2840, 1952, 1201], [3693, 2238, 1538, 947], 839 [2670, 1618, 1112, 684], [2022, 1226, 842, 518]], 840 [[4965, 3009, 2068, 1273], [3909, 2369, 1628, 1002], 841 [2805, 1700, 1168, 719], [2157, 1307, 898, 553]], 842 [[5253, 3183, 2188, 1347], [4134, 2506, 1722, 1060], 843 [2949, 1787, 1228, 756], [2301, 1394, 958, 590]], 844 [[5529, 3351, 2303, 1417], [4343, 2632, 1809, 1113], 845 [3081, 1867, 1283, 790], [2361, 1431, 983, 605]], 846 [[5836, 3537, 2431, 1496], [4588, 2780, 1911, 1176], 847 [3244, 1966, 1351, 832], [2524, 1530, 1051, 647]], 848 [[6153, 3729, 2563, 1577], [4775, 2894, 1989, 1224], 849 [3417, 2071, 1423, 876], [2625, 1591, 1093, 673]], 850 [[6479, 3927, 2699, 1661], [5039, 3054, 2099, 1292], 851 [3599, 2181, 1499, 923], [2735, 1658, 1139, 701]], 852 [[6743, 4087, 2809, 1729], [5313, 3220, 2213, 1362], 853 [3791, 2298, 1579, 972], [2927, 1774, 1219, 750]], 854 [[7089, 4296, 2953, 1817], [5596, 3391, 2331, 1435], 855 [3993, 2420, 1663, 1024], [3057, 1852, 1273, 784]], 856 ]; 857 858 /* $qr_ec_params[ */ 859 /* 4 * (version - 1) + (0 for L, 1 for M, 2 for Q, 3 for H) */ 860 /* ] = array( */ 861 /* total number of data codewords, */ 862 /* number of error correction codewords per block, */ 863 /* number of blocks in first group, */ 864 /* number of data codewords per block in first group, */ 865 /* number of blocks in second group, */ 866 /* number of data codewords per block in second group */ 867 /* ); */ 868 protected $qr_ec_params = [ 869 [19, 7, 1, 19, 0, 0], 870 [16, 10, 1, 16, 0, 0], 871 [13, 13, 1, 13, 0, 0], 872 [9, 17, 1, 9, 0, 0], 873 [34, 10, 1, 34, 0, 0], 874 [28, 16, 1, 28, 0, 0], 875 [22, 22, 1, 22, 0, 0], 876 [16, 28, 1, 16, 0, 0], 877 [55, 15, 1, 55, 0, 0], 878 [44, 26, 1, 44, 0, 0], 879 [34, 18, 2, 17, 0, 0], 880 [26, 22, 2, 13, 0, 0], 881 [80, 20, 1, 80, 0, 0], 882 [64, 18, 2, 32, 0, 0], 883 [48, 26, 2, 24, 0, 0], 884 [36, 16, 4, 9, 0, 0], 885 [108, 26, 1, 108, 0, 0], 886 [86, 24, 2, 43, 0, 0], 887 [62, 18, 2, 15, 2, 16], 888 [46, 22, 2, 11, 2, 12], 889 [136, 18, 2, 68, 0, 0], 890 [108, 16, 4, 27, 0, 0], 891 [76, 24, 4, 19, 0, 0], 892 [60, 28, 4, 15, 0, 0], 893 [156, 20, 2, 78, 0, 0], 894 [124, 18, 4, 31, 0, 0], 895 [88, 18, 2, 14, 4, 15], 896 [66, 26, 4, 13, 1, 14], 897 [194, 24, 2, 97, 0, 0], 898 [154, 22, 2, 38, 2, 39], 899 [110, 22, 4, 18, 2, 19], 900 [86, 26, 4, 14, 2, 15], 901 [232, 30, 2, 116, 0, 0], 902 [182, 22, 3, 36, 2, 37], 903 [132, 20, 4, 16, 4, 17], 904 [100, 24, 4, 12, 4, 13], 905 [274, 18, 2, 68, 2, 69], 906 [216, 26, 4, 43, 1, 44], 907 [154, 24, 6, 19, 2, 20], 908 [122, 28, 6, 15, 2, 16], 909 [324, 20, 4, 81, 0, 0], 910 [254, 30, 1, 50, 4, 51], 911 [180, 28, 4, 22, 4, 23], 912 [140, 24, 3, 12, 8, 13], 913 [370, 24, 2, 92, 2, 93], 914 [290, 22, 6, 36, 2, 37], 915 [206, 26, 4, 20, 6, 21], 916 [158, 28, 7, 14, 4, 15], 917 [428, 26, 4, 107, 0, 0], 918 [334, 22, 8, 37, 1, 38], 919 [244, 24, 8, 20, 4, 21], 920 [180, 22, 12, 11, 4, 12], 921 [461, 30, 3, 115, 1, 116], 922 [365, 24, 4, 40, 5, 41], 923 [261, 20, 11, 16, 5, 17], 924 [197, 24, 11, 12, 5, 13], 925 [523, 22, 5, 87, 1, 88], 926 [415, 24, 5, 41, 5, 42], 927 [295, 30, 5, 24, 7, 25], 928 [223, 24, 11, 12, 7, 13], 929 [589, 24, 5, 98, 1, 99], 930 [453, 28, 7, 45, 3, 46], 931 [325, 24, 15, 19, 2, 20], 932 [253, 30, 3, 15, 13, 16], 933 [647, 28, 1, 107, 5, 108], 934 [507, 28, 10, 46, 1, 47], 935 [367, 28, 1, 22, 15, 23], 936 [283, 28, 2, 14, 17, 15], 937 [721, 30, 5, 120, 1, 121], 938 [563, 26, 9, 43, 4, 44], 939 [397, 28, 17, 22, 1, 23], 940 [313, 28, 2, 14, 19, 15], 941 [795, 28, 3, 113, 4, 114], 942 [627, 26, 3, 44, 11, 45], 943 [445, 26, 17, 21, 4, 22], 944 [341, 26, 9, 13, 16, 14], 945 [861, 28, 3, 107, 5, 108], 946 [669, 26, 3, 41, 13, 42], 947 [485, 30, 15, 24, 5, 25], 948 [385, 28, 15, 15, 10, 16], 949 [932, 28, 4, 116, 4, 117], 950 [714, 26, 17, 42, 0, 0], 951 [512, 28, 17, 22, 6, 23], 952 [406, 30, 19, 16, 6, 17], 953 [1006, 28, 2, 111, 7, 112], 954 [782, 28, 17, 46, 0, 0], 955 [568, 30, 7, 24, 16, 25], 956 [442, 24, 34, 13, 0, 0], 957 [1094, 30, 4, 121, 5, 122], 958 [860, 28, 4, 47, 14, 48], 959 [614, 30, 11, 24, 14, 25], 960 [464, 30, 16, 15, 14, 16], 961 [1174, 30, 6, 117, 4, 118], 962 [914, 28, 6, 45, 14, 46], 963 [664, 30, 11, 24, 16, 25], 964 [514, 30, 30, 16, 2, 17], 965 [1276, 26, 8, 106, 4, 107], 966 [1000, 28, 8, 47, 13, 48], 967 [718, 30, 7, 24, 22, 25], 968 [538, 30, 22, 15, 13, 16], 969 [1370, 28, 10, 114, 2, 115], 970 [1062, 28, 19, 46, 4, 47], 971 [754, 28, 28, 22, 6, 23], 972 [596, 30, 33, 16, 4, 17], 973 [1468, 30, 8, 122, 4, 123], 974 [1128, 28, 22, 45, 3, 46], 975 [808, 30, 8, 23, 26, 24], 976 [628, 30, 12, 15, 28, 16], 977 [1531, 30, 3, 117, 10, 118], 978 [1193, 28, 3, 45, 23, 46], 979 [871, 30, 4, 24, 31, 25], 980 [661, 30, 11, 15, 31, 16], 981 [1631, 30, 7, 116, 7, 117], 982 [1267, 28, 21, 45, 7, 46], 983 [911, 30, 1, 23, 37, 24], 984 [701, 30, 19, 15, 26, 16], 985 [1735, 30, 5, 115, 10, 116], 986 [1373, 28, 19, 47, 10, 48], 987 [985, 30, 15, 24, 25, 25], 988 [745, 30, 23, 15, 25, 16], 989 [1843, 30, 13, 115, 3, 116], 990 [1455, 28, 2, 46, 29, 47], 991 [1033, 30, 42, 24, 1, 25], 992 [793, 30, 23, 15, 28, 16], 993 [1955, 30, 17, 115, 0, 0], 994 [1541, 28, 10, 46, 23, 47], 995 [1115, 30, 10, 24, 35, 25], 996 [845, 30, 19, 15, 35, 16], 997 [2071, 30, 17, 115, 1, 116], 998 [1631, 28, 14, 46, 21, 47], 999 [1171, 30, 29, 24, 19, 25], 1000 [901, 30, 11, 15, 46, 16], 1001 [2191, 30, 13, 115, 6, 116], 1002 [1725, 28, 14, 46, 23, 47], 1003 [1231, 30, 44, 24, 7, 25], 1004 [961, 30, 59, 16, 1, 17], 1005 [2306, 30, 12, 121, 7, 122], 1006 [1812, 28, 12, 47, 26, 48], 1007 [1286, 30, 39, 24, 14, 25], 1008 [986, 30, 22, 15, 41, 16], 1009 [2434, 30, 6, 121, 14, 122], 1010 [1914, 28, 6, 47, 34, 48], 1011 [1354, 30, 46, 24, 10, 25], 1012 [1054, 30, 2, 15, 64, 16], 1013 [2566, 30, 17, 122, 4, 123], 1014 [1992, 28, 29, 46, 14, 47], 1015 [1426, 30, 49, 24, 10, 25], 1016 [1096, 30, 24, 15, 46, 16], 1017 [2702, 30, 4, 122, 18, 123], 1018 [2102, 28, 13, 46, 32, 47], 1019 [1502, 30, 48, 24, 14, 25], 1020 [1142, 30, 42, 15, 32, 16], 1021 [2812, 30, 20, 117, 4, 118], 1022 [2216, 28, 40, 47, 7, 48], 1023 [1582, 30, 43, 24, 22, 25], 1024 [1222, 30, 10, 15, 67, 16], 1025 [2956, 30, 19, 118, 6, 119], 1026 [2334, 28, 18, 47, 31, 48], 1027 [1666, 30, 34, 24, 34, 25], 1028 [1276, 30, 20, 15, 61, 16], 1029 ]; 1030 1031 protected $qr_ec_polynomials = [ 1032 7 => [ 1033 0, 87, 229, 146, 149, 238, 102, 21 1034 ], 1035 10 => [ 1036 0, 251, 67, 46, 61, 118, 70, 64, 94, 32, 45 1037 ], 1038 13 => [ 1039 0, 74, 152, 176, 100, 86, 100, 1040 106, 104, 130, 218, 206, 140, 78 1041 ], 1042 15 => [ 1043 0, 8, 183, 61, 91, 202, 37, 51, 1044 58, 58, 237, 140, 124, 5, 99, 105 1045 ], 1046 16 => [ 1047 0, 120, 104, 107, 109, 102, 161, 76, 3, 1048 91, 191, 147, 169, 182, 194, 225, 120 1049 ], 1050 17 => [ 1051 0, 43, 139, 206, 78, 43, 239, 123, 206, 1052 214, 147, 24, 99, 150, 39, 243, 163, 136 1053 ], 1054 18 => [ 1055 0, 215, 234, 158, 94, 184, 97, 118, 170, 79, 1056 187, 152, 148, 252, 179, 5, 98, 96, 153 1057 ], 1058 20 => [ 1059 0, 17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 1060 221, 225, 83, 239, 156, 164, 212, 212, 188, 190 1061 ], 1062 22 => [ 1063 0, 210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 1064 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231 1065 ], 1066 24 => [ 1067 0, 229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 1068 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21 1069 ], 1070 26 => [ 1071 0, 173, 125, 158, 2, 103, 182, 118, 17, 1072 145, 201, 111, 28, 165, 53, 161, 21, 245, 1073 142, 13, 102, 48, 227, 153, 145, 218, 70 1074 ], 1075 28 => [ 1076 0, 168, 223, 200, 104, 224, 234, 108, 180, 1077 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 1078 245, 87, 42, 195, 212, 119, 242, 37, 9, 123 1079 ], 1080 30 => [ 1081 0, 41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 1082 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, 1083 224, 130, 156, 37, 251, 216, 238, 40, 192, 180 1084 ], 1085 ]; 1086 1087 protected $qr_log = [ 1088 0, 0, 1, 25, 2, 50, 26, 198, 1089 3, 223, 51, 238, 27, 104, 199, 75, 1090 4, 100, 224, 14, 52, 141, 239, 129, 1091 28, 193, 105, 248, 200, 8, 76, 113, 1092 5, 138, 101, 47, 225, 36, 15, 33, 1093 53, 147, 142, 218, 240, 18, 130, 69, 1094 29, 181, 194, 125, 106, 39, 249, 185, 1095 201, 154, 9, 120, 77, 228, 114, 166, 1096 6, 191, 139, 98, 102, 221, 48, 253, 1097 226, 152, 37, 179, 16, 145, 34, 136, 1098 54, 208, 148, 206, 143, 150, 219, 189, 1099 241, 210, 19, 92, 131, 56, 70, 64, 1100 30, 66, 182, 163, 195, 72, 126, 110, 1101 107, 58, 40, 84, 250, 133, 186, 61, 1102 202, 94, 155, 159, 10, 21, 121, 43, 1103 78, 212, 229, 172, 115, 243, 167, 87, 1104 7, 112, 192, 247, 140, 128, 99, 13, 1105 103, 74, 222, 237, 49, 197, 254, 24, 1106 227, 165, 153, 119, 38, 184, 180, 124, 1107 17, 68, 146, 217, 35, 32, 137, 46, 1108 55, 63, 209, 91, 149, 188, 207, 205, 1109 144, 135, 151, 178, 220, 252, 190, 97, 1110 242, 86, 211, 171, 20, 42, 93, 158, 1111 132, 60, 57, 83, 71, 109, 65, 162, 1112 31, 45, 67, 216, 183, 123, 164, 118, 1113 196, 23, 73, 236, 127, 12, 111, 246, 1114 108, 161, 59, 82, 41, 157, 85, 170, 1115 251, 96, 134, 177, 187, 204, 62, 90, 1116 203, 89, 95, 176, 156, 169, 160, 81, 1117 11, 245, 22, 235, 122, 117, 44, 215, 1118 79, 174, 213, 233, 230, 231, 173, 232, 1119 116, 214, 244, 234, 168, 80, 88, 175, 1120 ]; 1121 1122 protected $qr_exp = [ 1123 1, 2, 4, 8, 16, 32, 64, 128, 1124 29, 58, 116, 232, 205, 135, 19, 38, 1125 76, 152, 45, 90, 180, 117, 234, 201, 1126 143, 3, 6, 12, 24, 48, 96, 192, 1127 157, 39, 78, 156, 37, 74, 148, 53, 1128 106, 212, 181, 119, 238, 193, 159, 35, 1129 70, 140, 5, 10, 20, 40, 80, 160, 1130 93, 186, 105, 210, 185, 111, 222, 161, 1131 95, 190, 97, 194, 153, 47, 94, 188, 1132 101, 202, 137, 15, 30, 60, 120, 240, 1133 253, 231, 211, 187, 107, 214, 177, 127, 1134 254, 225, 223, 163, 91, 182, 113, 226, 1135 217, 175, 67, 134, 17, 34, 68, 136, 1136 13, 26, 52, 104, 208, 189, 103, 206, 1137 129, 31, 62, 124, 248, 237, 199, 147, 1138 59, 118, 236, 197, 151, 51, 102, 204, 1139 133, 23, 46, 92, 184, 109, 218, 169, 1140 79, 158, 33, 66, 132, 21, 42, 84, 1141 168, 77, 154, 41, 82, 164, 85, 170, 1142 73, 146, 57, 114, 228, 213, 183, 115, 1143 230, 209, 191, 99, 198, 145, 63, 126, 1144 252, 229, 215, 179, 123, 246, 241, 255, 1145 227, 219, 171, 75, 150, 49, 98, 196, 1146 149, 55, 110, 220, 165, 87, 174, 65, 1147 130, 25, 50, 100, 200, 141, 7, 14, 1148 28, 56, 112, 224, 221, 167, 83, 166, 1149 81, 162, 89, 178, 121, 242, 249, 239, 1150 195, 155, 43, 86, 172, 69, 138, 9, 1151 18, 36, 72, 144, 61, 122, 244, 245, 1152 247, 243, 251, 235, 203, 139, 11, 22, 1153 44, 88, 176, 125, 250, 233, 207, 131, 1154 27, 54, 108, 216, 173, 71, 142, 1, 1155 ]; 1156 1157 protected $qr_remainder_bits = [ 1158 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 1159 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1160 ]; 1161 1162 protected $qr_alignment_patterns = [ 1163 [6, 18], 1164 [6, 22], 1165 [6, 26], 1166 [6, 30], 1167 [6, 34], 1168 [6, 22, 38], 1169 [6, 24, 42], 1170 [6, 26, 46], 1171 [6, 28, 50], 1172 [6, 30, 54], 1173 [6, 32, 58], 1174 [6, 34, 62], 1175 [6, 26, 46, 66], 1176 [6, 26, 48, 70], 1177 [6, 26, 50, 74], 1178 [6, 30, 54, 78], 1179 [6, 30, 56, 82], 1180 [6, 30, 58, 86], 1181 [6, 34, 62, 90], 1182 [6, 28, 50, 72, 94], 1183 [6, 26, 50, 74, 98], 1184 [6, 30, 54, 78, 102], 1185 [6, 28, 54, 80, 106], 1186 [6, 32, 58, 84, 110], 1187 [6, 30, 58, 86, 114], 1188 [6, 34, 62, 90, 118], 1189 [6, 26, 50, 74, 98, 122], 1190 [6, 30, 54, 78, 102, 126], 1191 [6, 26, 52, 78, 104, 130], 1192 [6, 30, 56, 82, 108, 134], 1193 [6, 34, 60, 86, 112, 138], 1194 [6, 30, 58, 86, 114, 142], 1195 [6, 34, 62, 90, 118, 146], 1196 [6, 30, 54, 78, 102, 126, 150], 1197 [6, 24, 50, 76, 102, 128, 154], 1198 [6, 28, 54, 80, 106, 132, 158], 1199 [6, 32, 58, 84, 110, 136, 162], 1200 [6, 26, 54, 82, 110, 138, 166], 1201 [6, 30, 58, 86, 114, 142, 170], 1202 ]; 1203 1204 /* format info string = $qr_format_info[ */ 1205 /* (0 for L, 8 for M, 16 for Q, 24 for H) + mask */ 1206 /* ]; */ 1207 protected $qr_format_info = [ 1208 [1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0], 1209 [1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1], 1210 [1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0], 1211 [1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1], 1212 [1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1], 1213 [1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0], 1214 [1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1], 1215 [1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0], 1216 [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 1217 [1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1], 1218 [1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0], 1219 [1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1], 1220 [1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1], 1221 [1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0], 1222 [1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1], 1223 [1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0], 1224 [0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1], 1225 [0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0], 1226 [0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1], 1227 [0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0], 1228 [0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0], 1229 [0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1], 1230 [0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0], 1231 [0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1], 1232 [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1], 1233 [0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0], 1234 [0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1], 1235 [0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0], 1236 [0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0], 1237 [0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1], 1238 [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0], 1239 [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1], 1240 ]; 1241 1242 /* version info string = $qr_version_info[ (version - 7) ] */ 1243 protected $qr_version_info = [ 1244 [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0], 1245 [0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0], 1246 [0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1], 1247 [0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1], 1248 [0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0], 1249 [0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0], 1250 [0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1], 1251 [0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1], 1252 [0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0], 1253 [0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0], 1254 [0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1], 1255 [0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1], 1256 [0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0], 1257 [0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0], 1258 [0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1], 1259 [0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1], 1260 [0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0], 1261 [0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0], 1262 [0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1], 1263 [0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1], 1264 [0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0], 1265 [0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0], 1266 [0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1], 1267 [0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1], 1268 [0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0], 1269 [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1], 1270 [1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0], 1271 [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0], 1272 [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], 1273 [1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1], 1274 [1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0], 1275 [1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0], 1276 [1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1], 1277 [1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1], 1278 ]; 1279} 1280