php 生成二维码

Posted ziyandeyanhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 生成二维码相关的知识,希望对你有一定的参考价值。

生成二维码的类:

技术图片
   1 <?php
   2 
   3 /*
   4  * PHP QR Code encoder
   5  *
   6  * 此文件包含合并版本的PHP二维码库。
   7  * 它是自动生成的完整版本,为您的方便。
   8  *
   9  * 这个合并版本被配置为不需要任何外部文件,
  10  * 禁用缓存,错误日志和weker但更快的掩码匹配。
  11  * 如果您需要调整它,请使用非合并版本。
  12  *
  13  * For full version, documentation, examples of use please visit:
  14  *
  15  *    http://phpqrcode.sourceforge.net/
  16  *    https://sourceforge.net/projects/phpqrcode/
  17  *
  18  * PHP QR Code is distributed under LGPL 3
  19  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  20  *
  21  * 这个库是免费软件;你可以重新分配它
  22  * 根据GNU小团体的条款修改它
  23  * 由自由软件基金会发布的许可证;要么
  24  * 许可证的第三版,或任何更新版本。
  25  *
  26  * This library is distributed in the hope that it will be useful,
  27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  29  * Lesser General Public License for more details.
  30  *
  31  * You should have received a copy of the GNU Lesser General Public
  32  * License along with this library; if not, write to the Free Software
  33  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  34  */
  35  
  36  
  37 
  38 /*
  39  * Version: 1.1.4
  40  * Build: 2010100721
  41  */
  42 
  43 
  44 
  45 //---- qrconst.php -----------------------------
  46 
  47 
  48 
  49 
  50 
  51 /*
  52  * PHP QR Code encoder
  53  *
  54  * 常见的常量
  55  *
  56  * 基于libqrencode C库,分布在LGPL 2.1下
  57  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  58  *
  59  * PHP二维码是在LGPL 3下发布的
  60  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  61  *
  62  * This library is free software; you can redistribute it and/or
  63  * modify it under the terms of the GNU Lesser General Public
  64  * License as published by the Free Software Foundation; either
  65  * version 3 of the License, or any later version.
  66  *
  67  * This library is distributed in the hope that it will be useful,
  68  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  69  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  70  * Lesser General Public License for more details.
  71  *
  72  * You should have received a copy of the GNU Lesser General Public
  73  * License along with this library; if not, write to the Free Software
  74  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  75  */
  76  
  77     // Encoding modes
  78      
  79     define(‘QR_MODE_NUL‘, -1);
  80     define(‘QR_MODE_NUM‘, 0);
  81     define(‘QR_MODE_AN‘, 1);
  82     define(‘QR_MODE_8‘, 2);
  83     define(‘QR_MODE_KANJI‘, 3);
  84     define(‘QR_MODE_STRUCTURE‘, 4);
  85 
  86     // Levels of error correction.
  87 
  88     define(‘QR_ECLEVEL_L‘, 0);
  89     define(‘QR_ECLEVEL_M‘, 1);
  90     define(‘QR_ECLEVEL_Q‘, 2);
  91     define(‘QR_ECLEVEL_H‘, 3);
  92     
  93     // Supported output formats
  94     
  95     define(‘QR_FORMAT_TEXT‘, 0);
  96     define(‘QR_FORMAT_PNG‘,  1);
  97     
  98     class qrstr 
  99         public static function set(&$srctab, $x, $y, $repl, $replLen = false) 
 100             $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
 101         
 102         
 103 
 104 
 105 
 106 //---- merged_config.php -----------------------------
 107 
 108 
 109 
 110 
 111 /*
 112  * PHP QR Code encoder
 113  * PHP二维码编码器
 114  *
 115  * Config file, tuned-up for merged verion
 116  */
 117      
 118     define(‘QR_CACHEABLE‘, false);       // use cache - more disk reads but less CPU power, masks and format templates are stored there
 119     define(‘QR_CACHE_DIR‘, false);       // used when QR_CACHEABLE === true
 120     define(‘QR_LOG_DIR‘, false);         // default error logs dir   
 121     
 122     define(‘QR_FIND_BEST_MASK‘, true);                                                          // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code
 123     define(‘QR_FIND_FROM_RANDOM‘, 2);                                                       // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly
 124     define(‘QR_DEFAULT_MASK‘, 2);                                                               // when QR_FIND_BEST_MASK === false
 125                                                   
 126     define(‘QR_PNG_MAXIMUM_SIZE‘,  1024);                                                       // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images
 127                                                   
 128 
 129 
 130 
 131 //---- qrtools.php -----------------------------
 132 
 133 
 134 
 135 
 136 /*
 137  * PHP QR Code encoder
 138  * PHP二维码编码器
 139  *
 140  * Toolset, handy and debug utilites.
 141  * 工具集,方便和调试实用程序。
 142  *
 143  * PHP QR Code is distributed under LGPL 3
 144  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
 145  *
 146  * This library is free software; you can redistribute it and/or
 147  * modify it under the terms of the GNU Lesser General Public
 148  * License as published by the Free Software Foundation; either
 149  * version 3 of the License, or any later version.
 150  *
 151  * This library is distributed in the hope that it will be useful,
 152  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 153  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 154  * Lesser General Public License for more details.
 155  *
 156  * You should have received a copy of the GNU Lesser General Public
 157  * License along with this library; if not, write to the Free Software
 158  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 159  */
 160 
 161     class QRtools 
 162     
 163         //----------------------------------------------------------------------
 164         public static function binarize($frame)
 165         
 166             $len = count($frame);
 167             foreach ($frame as &$frameLine) 
 168                 
 169                 for($i=0; $i<$len; $i++) 
 170                     $frameLine[$i] = (ord($frameLine[$i])&1)?‘1‘:‘0‘;
 171                 
 172             
 173             
 174             return $frame;
 175         
 176         
 177         //----------------------------------------------------------------------
 178         public static function tcpdfBarcodeArray($code, $mode = ‘QR,L‘, $tcPdfVersion = ‘4.5.037‘)
 179         
 180             $barcode_array = array();
 181             
 182             if (!is_array($mode))
 183                 $mode = explode(‘,‘, $mode);
 184                 
 185             $eccLevel = ‘L‘;
 186                 
 187             if (count($mode) > 1) 
 188                 $eccLevel = $mode[1];
 189             
 190                 
 191             $qrTab = QRcode::text($code, false, $eccLevel);
 192             $size = count($qrTab);
 193                 
 194             $barcode_array[‘num_rows‘] = $size;
 195             $barcode_array[‘num_cols‘] = $size;
 196             $barcode_array[‘bcode‘] = array();
 197                 
 198             foreach ($qrTab as $line) 
 199                 $arrAdd = array();
 200                 foreach(str_split($line) as $char)
 201                     $arrAdd[] = ($char==‘1‘)?1:0;
 202                 $barcode_array[‘bcode‘][] = $arrAdd;
 203             
 204                     
 205             return $barcode_array;
 206         
 207         
 208         //----------------------------------------------------------------------
 209         public static function clearCache()
 210         
 211             self::$frames = array();
 212         
 213         
 214         //----------------------------------------------------------------------
 215         public static function buildCache()
 216         
 217             QRtools::markTime(‘before_build_cache‘);
 218             
 219             $mask = new QRmask();
 220             for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) 
 221                 $frame = QRspec::newFrame($a);
 222                 if (QR_IMAGE) 
 223                     $fileName = QR_CACHE_DIR.‘frame_‘.$a.‘.png‘;
 224                     QRimage::png(self::binarize($frame), $fileName, 1, 0);
 225                 
 226                 
 227                 $width = count($frame);
 228                 $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
 229                 for ($maskNo=0; $maskNo<8; $maskNo++)
 230                     $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
 231             
 232             
 233             QRtools::markTime(‘after_build_cache‘);
 234         
 235 
 236         //----------------------------------------------------------------------
 237         public static function log($outfile, $err)
 238         
 239             if (QR_LOG_DIR !== false) 
 240                 if ($err != ‘‘) 
 241                     if ($outfile !== false) 
 242                         file_put_contents(QR_LOG_DIR.basename($outfile).‘-errors.txt‘, date(‘Y-m-d H:i:s‘).‘: ‘.$err, FILE_APPEND);
 243                      else 
 244                         file_put_contents(QR_LOG_DIR.‘errors.txt‘, date(‘Y-m-d H:i:s‘).‘: ‘.$err, FILE_APPEND);
 245                     
 246                     
 247             
 248         
 249         
 250         //----------------------------------------------------------------------
 251         public static function dumpMask($frame) 
 252         
 253             $width = count($frame);
 254             for($y=0;$y<$width;$y++) 
 255                 for($x=0;$x<$width;$x++) 
 256                     echo ord($frame[$y][$x]).‘,‘;
 257                 
 258             
 259         
 260         
 261         //----------------------------------------------------------------------
 262         public static function markTime($markerId)
 263         
 264             list($usec, $sec) = explode(" ", microtime());
 265             $time = ((float)$usec + (float)$sec);
 266             
 267             if (!isset($GLOBALS[‘qr_time_bench‘]))
 268                 $GLOBALS[‘qr_time_bench‘] = array();
 269             
 270             $GLOBALS[‘qr_time_bench‘][$markerId] = $time;
 271         
 272         
 273         //----------------------------------------------------------------------
 274         public static function timeBenchmark()
 275         
 276             self::markTime(‘finish‘);
 277         
 278             $lastTime = 0;
 279             $startTime = 0;
 280             $p = 0;
 281 
 282             echo<table cellpadding="3" cellspacing="1">
 283                     <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
 284                     <tbody>‘;
 285 
 286             foreach($GLOBALS[‘qr_time_bench‘] as $markerId=>$thisTime) 
 287                 if ($p > 0) 
 288                     echo ‘<tr><th style="text-align:right">till ‘.$markerId.‘: </th><td>‘.number_format($thisTime-$lastTime, 6).‘s</td></tr>‘;
 289                  else 
 290                     $startTime = $thisTime;
 291                 
 292                 
 293                 $p++;
 294                 $lastTime = $thisTime;
 295             
 296             
 297             echo</tbody><tfoot>
 298                 <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>‘.number_format($lastTime-$startTime, 6).‘s</td></tr>
 299             </tfoot>
 300             </table>‘;
 301         
 302         
 303     
 304     
 305     //##########################################################################
 306     
 307     QRtools::markTime(‘start‘);
 308     
 309 
 310 
 311 
 312 //---- qrspec.php -----------------------------
 313 
 314 
 315 
 316 
 317 /*
 318  * PHP QR Code encoder
 319  *
 320  * QR Code specifications
 321  * 二维码的规范
 322  *
 323  * Based on libqrencode C library distributed under LGPL 2.1
 324  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
 325  *
 326  * PHP QR Code is distributed under LGPL 3
 327  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
 328  *
 329  * The following data / specifications are taken from
 330  * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
 331  *  or
 332  * "Automatic identification and data capture techniques -- 
 333  *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
 334  *
 335  * This library is free software; you can redistribute it and/or
 336  * modify it under the terms of the GNU Lesser General Public
 337  * License as published by the Free Software Foundation; either
 338  * version 3 of the License, or any later version.
 339  *
 340  * This library is distributed in the hope that it will be useful,
 341  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 342  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 343  * Lesser General Public License for more details.
 344  *
 345  * You should have received a copy of the GNU Lesser General Public
 346  * License along with this library; if not, write to the Free Software
 347  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 348  */
 349  
 350     define(‘QRSPEC_VERSION_MAX‘, 40);
 351     define(‘QRSPEC_WIDTH_MAX‘,   177);
 352 
 353     define(‘QRCAP_WIDTH‘,        0);
 354     define(‘QRCAP_WORDS‘,        1);
 355     define(‘QRCAP_REMINDER‘,     2);
 356     define(‘QRCAP_EC‘,           3);
 357 
 358     class QRspec 
 359     
 360         public static $capacity = array(
 361             array(  0,    0, 0, array(   0,    0,    0,    0)),
 362             array( 21,   26, 0, array(   7,   10,   13,   17)), // 1
 363             array( 25,   44, 7, array(  10,   16,   22,   28)),
 364             array( 29,   70, 7, array(  15,   26,   36,   44)),
 365             array( 33,  100, 7, array(  20,   36,   52,   64)),
 366             array( 37,  134, 7, array(  26,   48,   72,   88)), // 5
 367             array( 41,  172, 7, array(  36,   64,   96,  112)),
 368             array( 45,  196, 0, array(  40,   72,  108,  130)),
 369             array( 49,  242, 0, array(  48,   88,  132,  156)),
 370             array( 53,  292, 0, array(  60,  110,  160,  192)),
 371             array( 57,  346, 0, array(  72,  130,  192,  224)), //10
 372             array( 61,  404, 0, array(  80,  150,  224,  264)),
 373             array( 65,  466, 0, array(  96,  176,  260,  308)),
 374             array( 69,  532, 0, array( 104,  198,  288,  352)),
 375             array( 73,  581, 3, array( 120,  216,  320,  384)),
 376             array( 77,  655, 3, array( 132,  240,  360,  432)), //15
 377             array( 81,  733, 3, array( 144,  280,  408,  480)),
 378             array( 85,  815, 3, array( 168,  308,  448,  532)),
 379             array( 89,  901, 3, array( 180,  338,  504,  588)),
 380             array( 93,  991, 3, array( 196,  364,  546,  650)),
 381             array( 97, 1085, 3, array( 224,  416,  600,  700)), //20
 382             array(101, 1156, 4, array( 224,  442,  644,  750)),
 383             array(105, 1258, 4, array( 252,  476,  690,  816)),
 384             array(109, 1364, 4, array( 270,  504,  750,  900)),
 385             array(113, 1474, 4, array( 300,  560,  810,  960)),
 386             array(117, 1588, 4, array( 312,  588,  870, 1050)), //25
 387             array(121, 1706, 4, array( 336,  644,  952, 1110)),
 388             array(125, 1828, 4, array( 360,  700, 1020, 1200)),
 389             array(129, 1921, 3, array( 390,  728, 1050, 1260)),
 390             array(133, 2051, 3, array( 420,  784, 1140, 1350)),
 391             array(137, 2185, 3, array( 450,  812, 1200, 1440)), //30
 392             array(141, 2323, 3, array( 480,  868, 1290, 1530)),
 393             array(145, 2465, 3, array( 510,  924, 1350, 1620)),
 394             array(149, 2611, 3, array( 540,  980, 1440, 1710)),
 395             array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
 396             array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
 397             array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
 398             array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
 399             array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
 400             array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
 401             array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
 402         );
 403         
 404         //----------------------------------------------------------------------
 405         public static function getDataLength($version, $level)
 406         
 407             return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
 408         
 409         
 410         //----------------------------------------------------------------------
 411         public static function getECCLength($version, $level)
 412         
 413             return self::$capacity[$version][QRCAP_EC][$level];
 414         
 415         
 416         //----------------------------------------------------------------------
 417         public static function getWidth($version)
 418         
 419             return self::$capacity[$version][QRCAP_WIDTH];
 420         
 421         
 422         //----------------------------------------------------------------------
 423         public static function getRemainder($version)
 424         
 425             return self::$capacity[$version][QRCAP_REMINDER];
 426         
 427         
 428         //----------------------------------------------------------------------
 429         public static function getMinimumVersion($size, $level)
 430         
 431 
 432             for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) 
 433                 $words  = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
 434                 if($words >= $size) 
 435                     return $i;
 436             
 437 
 438             return -1;
 439         
 440     
 441         //######################################################################
 442         
 443         public static $lengthTableBits = array(
 444             array(10, 12, 14),
 445             array( 9, 11, 13),
 446             array( 8, 16, 16),
 447             array( 8, 10, 12)
 448         );
 449         
 450         //----------------------------------------------------------------------
 451         public static function lengthIndicator($mode, $version)
 452         
 453             if ($mode == QR_MODE_STRUCTURE)
 454                 return 0;
 455                 
 456             if ($version <= 9) 
 457                 $l = 0;
 458              else if ($version <= 26) 
 459                 $l = 1;
 460              else 
 461                 $l = 2;
 462             
 463 
 464             return self::$lengthTableBits[$mode][$l];
 465         
 466         
 467         //----------------------------------------------------------------------
 468         public static function maximumWords($mode, $version)
 469         
 470             if($mode == QR_MODE_STRUCTURE) 
 471                 return 3;
 472                 
 473             if($version <= 9) 
 474                 $l = 0;
 475              else if($version <= 26) 
 476                 $l = 1;
 477              else 
 478                 $l = 2;
 479             
 480 
 481             $bits = self::$lengthTableBits[$mode][$l];
 482             $words = (1 << $bits) - 1;
 483             
 484             if($mode == QR_MODE_KANJI) 
 485                 $words *= 2; // the number of bytes is required
 486             
 487 
 488             return $words;
 489         
 490 
 491         // Error correction code -----------------------------------------------
 492         // Table of the error correction code (Reed-Solomon block)
 493         // See Table 12-16 (pp.30-36), JIS X0510:2004.
 494 
 495         public static $eccTable = array(
 496             array(array( 0,  0), array( 0,  0), array( 0,  0), array( 0,  0)),
 497             array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)), // 1
 498             array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)),
 499             array(array( 1,  0), array( 1,  0), array( 2,  0), array( 2,  0)),
 500             array(array( 1,  0), array( 2,  0), array( 2,  0), array( 4,  0)),
 501             array(array( 1,  0), array( 2,  0), array( 2,  2), array( 2,  2)), // 5
 502             array(array( 2,  0), array( 4,  0), array( 4,  0), array( 4,  0)),
 503             array(array( 2,  0), array( 4,  0), array( 2,  4), array( 4,  1)),
 504             array(array( 2,  0), array( 2,  2), array( 4,  2), array( 4,  2)),
 505             array(array( 2,  0), array( 3,  2), array( 4,  4), array( 4,  4)),
 506             array(array( 2,  2), array( 4,  1), array( 6,  2), array( 6,  2)), //10
 507             array(array( 4,  0), array( 1,  4), array( 4,  4), array( 3,  8)),
 508             array(array( 2,  2), array( 6,  2), array( 4,  6), array( 7,  4)),
 509             array(array( 4,  0), array( 8,  1), array( 8,  4), array(12,  4)),
 510             array(array( 3,  1), array( 4,  5), array(11,  5), array(11,  5)),
 511             array(array( 5,  1), array( 5,  5), array( 5,  7), array(11,  7)), //15
 512             array(array( 5,  1), array( 7,  3), array(15,  2), array( 3, 13)),
 513             array(array( 1,  5), array(10,  1), array( 1, 15), array( 2, 17)),
 514             array(array( 5,  1), array( 9,  4), array(17,  1), array( 2, 19)),
 515             array(array( 3,  4), array( 3, 11), array(17,  4), array( 9, 16)),
 516             array(array( 3,  5), array( 3, 13), array(15,  5), array(15, 10)), //20
 517             array(array( 4,  4), array(17,  0), array(17,  6), array(19,  6)),
 518             array(array( 2,  7), array(17,  0), array( 7, 16), array(34,  0)),
 519             array(array( 4,  5), array( 4, 14), array(11, 14), array(16, 14)),
 520             array(array( 6,  4), array( 6, 14), array(11, 16), array(30,  2)),
 521             array(array( 8,  4), array( 8, 13), array( 7, 22), array(22, 13)), //25
 522             array(array(10,  2), array(19,  4), array(28,  6), array(33,  4)),
 523             array(array( 8,  4), array(22,  3), array( 8, 26), array(12, 28)),
 524             array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
 525             array(array( 7,  7), array(21,  7), array( 1, 37), array(19, 26)),
 526             array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
 527             array(array(13,  3), array( 2, 29), array(42,  1), array(23, 28)),
 528             array(array(17,  0), array(10, 23), array(10, 35), array(19, 35)),
 529             array(array(17,  1), array(14, 21), array(29, 19), array(11, 46)),
 530             array(array(13,  6), array(14, 23), array(44,  7), array(59,  1)),
 531             array(array(12,  7), array(12, 26), array(39, 14), array(22, 41)), //35
 532             array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
 533             array(array(17,  4), array(29, 14), array(49, 10), array(24, 46)),
 534             array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
 535             array(array(20,  4), array(40,  7), array(43, 22), array(10, 67)),
 536             array(array(19,  6), array(18, 31), array(34, 34), array(20, 61)),//40
 537         );                                                                       
 538 
 539         //----------------------------------------------------------------------
 540         // CACHEABLE!!!
 541         
 542         public static function getEccSpec($version, $level, array &$spec)
 543         
 544             if (count($spec) < 5) 
 545                 $spec = array(0,0,0,0,0);
 546             
 547 
 548             $b1   = self::$eccTable[$version][$level][0];
 549             $b2   = self::$eccTable[$version][$level][1];
 550             $data = self::getDataLength($version, $level);
 551             $ecc  = self::getECCLength($version, $level);
 552 
 553             if($b2 == 0) 
 554                 $spec[0] = $b1;
 555                 $spec[1] = (int)($data / $b1);
 556                 $spec[2] = (int)($ecc / $b1);
 557                 $spec[3] = 0; 
 558                 $spec[4] = 0;
 559              else 
 560                 $spec[0] = $b1;
 561                 $spec[1] = (int)($data / ($b1 + $b2));
 562                 $spec[2] = (int)($ecc  / ($b1 + $b2));
 563                 $spec[3] = $b2;
 564                 $spec[4] = $spec[1] + 1;
 565             
 566         
 567 
 568         // Alignment pattern ---------------------------------------------------
 569 
 570         // Positions of alignment patterns.
 571         // This array includes only the second and the third position of the 
 572         // alignment patterns. Rest of them can be calculated from the distance 
 573         // between them.
 574          
 575         // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
 576          
 577         public static $alignmentPattern = array(      
 578             array( 0,  0),
 579             array( 0,  0), array(18,  0), array(22,  0), array(26,  0), array(30,  0), // 1- 5
 580             array(34,  0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
 581             array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
 582             array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
 583             array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
 584             array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
 585             array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
 586             array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
 587         );                                                                                  
 588 
 589         
 590         /** --------------------------------------------------------------------
 591          * Put an alignment marker.
 592          * @param frame
 593          * @param width
 594          * @param ox,oy center coordinate of the pattern
 595          */
 596         public static function putAlignmentMarker(array &$frame, $ox, $oy)
 597         
 598             $finder = array(
 599                 "\xa1\xa1\xa1\xa1\xa1",
 600                 "\xa1\xa0\xa0\xa0\xa1",
 601                 "\xa1\xa0\xa1\xa0\xa1",
 602                 "\xa1\xa0\xa0\xa0\xa1",
 603                 "\xa1\xa1\xa1\xa1\xa1"
 604             );                        
 605             
 606             $yStart = $oy-2;         
 607             $xStart = $ox-2;
 608             
 609             for($y=0; $y<5; $y++) 
 610                 QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);
 611             
 612         
 613 
 614         //----------------------------------------------------------------------
 615         public static function putAlignmentPattern($version, &$frame, $width)
 616         
 617             if($version < 2)
 618                 return;
 619 
 620             $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
 621             if($d < 0) 
 622                 $w = 2;
 623              else 
 624                 $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);
 625             
 626 
 627             if($w * $w - 3 == 1) 
 628                 $x = self::$alignmentPattern[$version][0];
 629                 $y = self::$alignmentPattern[$version][0];
 630                 self::putAlignmentMarker($frame, $x, $y);
 631                 return;
 632             
 633 
 634             $cx = self::$alignmentPattern[$version][0];
 635             for($x=1; $x<$w - 1; $x++) 
 636                 self::putAlignmentMarker($frame, 6, $cx);
 637                 self::putAlignmentMarker($frame, $cx,  6);
 638                 $cx += $d;
 639             
 640 
 641             $cy = self::$alignmentPattern[$version][0];
 642             for($y=0; $y<$w-1; $y++) 
 643                 $cx = self::$alignmentPattern[$version][0];
 644                 for($x=0; $x<$w-1; $x++) 
 645                     self::putAlignmentMarker($frame, $cx, $cy);
 646                     $cx += $d;
 647                 
 648                 $cy += $d;
 649             
 650         
 651 
 652         // Version information pattern -----------------------------------------
 653 
 654         // Version information pattern (BCH coded).
 655         // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
 656         
 657         // size: [QRSPEC_VERSION_MAX - 6]
 658         
 659         public static $versionPattern = array(
 660             0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
 661             0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
 662             0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
 663             0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
 664             0x27541, 0x28c69
 665         );
 666 
 667         //----------------------------------------------------------------------
 668         public static function getVersionPattern($version)
 669         
 670             if($version < 7 || $version > QRSPEC_VERSION_MAX)
 671                 return 0;
 672 
 673             return self::$versionPattern[$version -7];
 674         
 675 
 676         // Format information --------------------------------------------------
 677         // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
 678         
 679         public static $formatInfo = array(
 680             array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
 681             array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
 682             array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
 683             array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
 684         );
 685 
 686         public static function getFormatInfo($mask, $level)
 687         
 688             if($mask < 0 || $mask > 7)
 689                 return 0;
 690                 
 691             if($level < 0 || $level > 3)
 692                 return 0;                
 693 
 694             return self::$formatInfo[$level][$mask];
 695         
 696 
 697         // Frame ---------------------------------------------------------------
 698         // Cache of initial frames.
 699          
 700         public static $frames = array();
 701 
 702         /** --------------------------------------------------------------------
 703          * Put a finder pattern.
 704          * @param frame
 705          * @param width
 706          * @param ox,oy upper-left coordinate of the pattern
 707          */
 708         public static function putFinderPattern(&$frame, $ox, $oy)
 709         
 710             $finder = array(
 711                 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
 712                 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
 713                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
 714                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
 715                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
 716                 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
 717                 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
 718             );                            
 719             
 720             for($y=0; $y<7; $y++) 
 721                 QRstr::set($frame, $ox, $oy+$y, $finder[$y]);
 722             
 723         
 724 
 725         //----------------------------------------------------------------------
 726         public static function createFrame($version)
 727         
 728             $width = self::$capacity[$version][QRCAP_WIDTH];
 729             $frameLine = str_repeat ("\0", $width);
 730             $frame = array_fill(0, $width, $frameLine);
 731 
 732             // Finder pattern
 733             self::putFinderPattern($frame, 0, 0);
 734             self::putFinderPattern($frame, $width - 7, 0);
 735             self::putFinderPattern($frame, 0, $width - 7);
 736             
 737             // Separator
 738             $yOffset = $width - 7;
 739             
 740             for($y=0; $y<7; $y++) 
 741                 $frame[$y][7] = "\xc0";
 742                 $frame[$y][$width - 8] = "\xc0";
 743                 $frame[$yOffset][7] = "\xc0";
 744                 $yOffset++;
 745             
 746             
 747             $setPattern = str_repeat("\xc0", 8);
 748             
 749             QRstr::set($frame, 0, 7, $setPattern);
 750             QRstr::set($frame, $width-8, 7, $setPattern);
 751             QRstr::set($frame, 0, $width - 8, $setPattern);
 752         
 753             // Format info
 754             $setPattern = str_repeat("\x84", 9);
 755             QRstr::set($frame, 0, 8, $setPattern);
 756             QRstr::set($frame, $width - 8, 8, $setPattern, 8);
 757             
 758             $yOffset = $width - 8;
 759 
 760             for($y=0; $y<8; $y++,$yOffset++) 
 761                 $frame[$y][8] = "\x84";
 762                 $frame[$yOffset][8] = "\x84";
 763             
 764 
 765             // Timing pattern  
 766             
 767             for($i=1; $i<$width-15; $i++) 
 768                 $frame[6][7+$i] = chr(0x90 | ($i & 1));
 769                 $frame[7+$i][6] = chr(0x90 | ($i & 1));
 770             
 771             
 772             // Alignment pattern  
 773             self::putAlignmentPattern($version, $frame, $width);
 774             
 775             // Version information 
 776             if($version >= 7) 
 777                 $vinf = self::getVersionPattern($version);
 778 
 779                 $v = $vinf;
 780                 
 781                 for($x=0; $x<6; $x++) 
 782                     for($y=0; $y<3; $y++) 
 783                         $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));
 784                         $v = $v >> 1;
 785                     
 786                 
 787 
 788                 $v = $vinf;
 789                 for($y=0; $y<6; $y++) 
 790                     for($x=0; $x<3; $x++) 
 791                         $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));
 792                         $v = $v >> 1;
 793                     
 794                 
 795             
 796     
 797             // and a little bit...  
 798             $frame[$width - 8][8] = "\x81";
 799             
 800             return $frame;
 801         
 802 
 803         //----------------------------------------------------------------------
 804         public static function debug($frame, $binary_mode = false)
 805         
 806             if ($binary_mode) 
 807             
 808                     foreach ($frame as &$frameLine) 
 809                         $frameLine = join(‘<span class="m">&nbsp;&nbsp;</span>‘, explode(‘0‘, $frameLine));
 810                         $frameLine = join(‘&#9608;&#9608;‘, explode(‘1‘, $frameLine));
 811                     
 812                     
 813                     ?>
 814                 <style>
 815                     .m  background-color: white; 
 816                 </style>
 817                 <?php
 818                     echo ‘<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;‘;
 819                     echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);
 820                     echo ‘</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >‘;
 821             
 822              else 
 823             
 824                 foreach ($frame as &$frameLine) 
 825                     $frameLine = join(‘<span class="m">&nbsp;</span>‘,  explode("\xc0", $frameLine));
 826                     $frameLine = join(‘<span class="m">&#9618;</span>‘, explode("\xc1", $frameLine));
 827                     $frameLine = join(‘<span class="p">&nbsp;</span>‘,  explode("\xa0", $frameLine));
 828                     $frameLine = join(‘<span class="p">&#9618;</span>‘, explode("\xa1", $frameLine));
 829                     $frameLine = join(‘<span class="s">&#9671;</span>‘, explode("\x84", $frameLine)); //format 0
 830                     $frameLine = join(‘<span class="s">&#9670;</span>‘, explode("\x85", $frameLine)); //format 1
 831                     $frameLine = join(‘<span class="x">&#9762;</span>‘, explode("\x81", $frameLine)); //special bit
 832                     $frameLine = join(‘<span class="c">&nbsp;</span>‘,  explode("\x90", $frameLine)); //clock 0
 833                     $frameLine = join(‘<span class="c">&#9719;</span>‘, explode("\x91", $frameLine)); //clock 1
 834                     $frameLine = join(‘<span class="f">&nbsp;</span>‘,  explode("\x88", $frameLine)); //version
 835                     $frameLine = join(‘<span class="f">&#9618;</span>‘, explode("\x89", $frameLine)); //version
 836                     $frameLine = join(‘&#9830;‘, explode("\x01", $frameLine));
 837                     $frameLine = join(‘&#8901;‘, explode("\0", $frameLine));
 838                 
 839                 
 840                 ?>
 841                 <style>
 842                     .p  background-color: yellow; 
 843                     .m  background-color: #00FF00; 
 844                     .s  background-color: #FF0000; 
 845                     .c  background-color: aqua; 
 846                     .x  background-color: pink; 
 847                     .f  background-color: gold; 
 848                 </style>
 849                 <?php
 850                 echo "<pre><tt>";
 851                 echo join("<br/ >", $frame);
 852                 echo "</tt></pre>";
 853             
 854             
 855         
 856 
 857         //----------------------------------------------------------------------
 858         public static function serial($frame)
 859         
 860             return gzcompress(join("\n", $frame), 9);
 861         
 862         
 863         //----------------------------------------------------------------------
 864         public static function unserial($code)
 865         
 866             return explode("\n", gzuncompress($code));
 867         
 868         
 869         //----------------------------------------------------------------------
 870         public static function newFrame($version)
 871         
 872             if($version < 1 || $version > QRSPEC_VERSION_MAX) 
 873                 return null;
 874 
 875             if(!isset(self::$frames[$version])) 
 876                 
 877                 $fileName = QR_CACHE_DIR.‘frame_‘.$version.‘.dat‘;
 878                 
 879                 if (QR_CACHEABLE) 
 880                     if (file_exists($fileName)) 
 881                         self::$frames[$version] = self::unserial(file_get_contents($fileName));
 882                      else 
 883                         self::$frames[$version] = self::createFrame($version);
 884                         file_put_contents($fileName, self::serial(self::$frames[$version]));
 885                     
 886                  else 
 887                     self::$frames[$version] = self::createFrame($version);
 888                 
 889             
 890             
 891             if(is_null(self::$frames[$version]))
 892                 return null;
 893 
 894             return self::$frames[$version];
 895         
 896 
 897         //----------------------------------------------------------------------
 898         public static function rsBlockNum($spec)      return $spec[0] + $spec[3]; 
 899         public static function rsBlockNum1($spec)     return $spec[0]; 
 900         public static function rsDataCodes1($spec)    return $spec[1]; 
 901         public static function rsEccCodes1($spec)     return $spec[2]; 
 902         public static function rsBlockNum2($spec)     return $spec[3]; 
 903         public static function rsDataCodes2($spec)    return $spec[4]; 
 904         public static function rsEccCodes2($spec)     return $spec[2]; 
 905         public static function rsDataLength($spec)    return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);    
 906         public static function rsEccLength($spec)     return ($spec[0] + $spec[3]) * $spec[2]; 
 907         
 908     
 909 
 910 
 911 
 912 //---- qrimage.php -----------------------------
 913 
 914 
 915 
 916 
 917 /*
 918  * PHP QR Code encoder
 919  *
 920  * Image output of code using GD2
 921  * 图像输出的代码使用GD2
 922  *
 923  * PHP QR Code is distributed under LGPL 3
 924  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
 925  *
 926  * This library is free software; you can redistribute it and/or
 927  * modify it under the terms of the GNU Lesser General Public
 928  * License as published by the Free Software Foundation; either
 929  * version 3 of the License, or any later version.
 930  *
 931  * This library is distributed in the hope that it will be useful,
 932  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 933  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 934  * Lesser General Public License for more details.
 935  *
 936  * You should have received a copy of the GNU Lesser General Public
 937  * License along with this library; if not, write to the Free Software
 938  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 939  */
 940  
 941     define(‘QR_IMAGE‘, true);
 942 
 943     class QRimage 
 944     
 945         //----------------------------------------------------------------------
 946         public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) 
 947         
 948             $image = self::image($frame, $pixelPerPoint, $outerFrame);
 949             
 950             if ($filename === false) 
 951                 Header("Content-type: image/png");
 952                 ImagePng($image);
 953              else 
 954                 if($saveandprint===TRUE)
 955                     ImagePng($image, $filename);
 956                     header("Content-type: image/png");
 957                     ImagePng($image);
 958                 else
 959                     ImagePng($image, $filename);
 960                 
 961             
 962             
 963             ImageDestroy($image);
 964         
 965     
 966         //----------------------------------------------------------------------
 967         public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) 
 968         
 969             $image = self::image($frame, $pixelPerPoint, $outerFrame);
 970             
 971             if ($filename === false) 
 972                 Header("Content-type: image/jpeg");
 973                 ImageJpeg($image, null, $q);
 974              else 
 975                 ImageJpeg($image, $filename, $q);            
 976             
 977             
 978             ImageDestroy($image);
 979         
 980     
 981         //----------------------------------------------------------------------
 982         private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) 
 983         
 984             $h = count($frame);
 985             $w = strlen($frame[0]);
 986             
 987             $imgW = $w + 2*$outerFrame;
 988             $imgH = $h + 2*$outerFrame;
 989             
 990             $base_image =ImageCreate($imgW, $imgH);
 991             
 992             $col[0] = ImageColorAllocate($base_image,255,255,255);
 993             $col[1] = ImageColorAllocate($base_image,0,0,0);
 994 
 995             imagefill($base_image, 0, 0, $col[0]);
 996 
 997             for($y=0; $y<$h; $y++) 
 998                 for($x=0; $x<$w; $x++) 
 999                     if ($frame[$y][$x] == ‘1‘) 
1000                         ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); 
1001                     
1002                 
1003             
1004             
1005             $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
1006             ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
1007             ImageDestroy($base_image);
1008             
1009             return $target_image;
1010         
1011     
1012 
1013 
1014 
1015 //---- qrinput.php -----------------------------
1016 
1017 
1018 
1019 
1020 /*
1021  * PHP QR Code encoder
1022  *
1023  * Input encoding class
1024  * 输入编码类
1025  *
1026  * Based on libqrencode C library distributed under LGPL 2.1
1027  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1028  *
1029  * PHP QR Code is distributed under LGPL 3
1030  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1031  *
1032  * This library is free software; you can redistribute it and/or
1033  * modify it under the terms of the GNU Lesser General Public
1034  * License as published by the Free Software Foundation; either
1035  * version 3 of the License, or any later version.
1036  *
1037  * This library is distributed in the hope that it will be useful,
1038  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1039  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1040  * Lesser General Public License for more details.
1041  *
1042  * You should have received a copy of the GNU Lesser General Public
1043  * License along with this library; if not, write to the Free Software
1044  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1045  */
1046  
1047     define(‘STRUCTURE_HEADER_BITS‘,  20);
1048     define(‘MAX_STRUCTURED_SYMBOLS‘, 16);
1049 
1050     class QRinputItem 
1051     
1052         public $mode;
1053         public $size;
1054         public $data;
1055         public $bstream;
1056 
1057         public function __construct($mode, $size, $data, $bstream = null) 
1058         
1059             $setData = array_slice($data, 0, $size);
1060             
1061             if (count($setData) < $size) 
1062                 $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
1063             
1064         
1065             if(!QRinput::check($mode, $size, $setData)) 
1066                 throw new Exception(‘Error m:‘.$mode.‘,s:‘.$size.‘,d:‘.join(‘,‘,$setData));
1067                 return null;
1068             
1069             
1070             $this->mode = $mode;
1071             $this->size = $size;
1072             $this->data = $setData;
1073             $this->bstream = $bstream;
1074         
1075         
1076         //----------------------------------------------------------------------
1077         public function encodeModeNum($version)
1078         
1079             try 
1080             
1081                 $words = (int)($this->size / 3);
1082                 $bs = new QRbitstream();
1083                 
1084                 $val = 0x1;
1085                 $bs->appendNum(4, $val);
1086                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
1087 
1088                 for($i=0; $i<$words; $i++) 
1089                     $val  = (ord($this->data[$i*3  ]) - ord(‘0‘)) * 100;
1090                     $val += (ord($this->data[$i*3+1]) - ord(‘0‘)) * 10;
1091                     $val += (ord($this->data[$i*3+2]) - ord(‘0‘));
1092                     $bs->appendNum(10, $val);
1093                 
1094 
1095                 if($this->size - $words * 3 == 1) 
1096                     $val = ord($this->data[$words*3]) - ord(‘0‘);
1097                     $bs->appendNum(4, $val);
1098                  else if($this->size - $words * 3 == 2) 
1099                     $val  = (ord($this->data[$words*3  ]) - ord(‘0‘)) * 10;
1100                     $val += (ord($this->data[$words*3+1]) - ord(‘0‘));
1101                     $bs->appendNum(7, $val);
1102                 
1103 
1104                 $this->bstream = $bs;
1105                 return 0;
1106                 
1107              catch (Exception $e) 
1108                 return -1;
1109             
1110         
1111         
1112         //----------------------------------------------------------------------
1113         public function encodeModeAn($version)
1114         
1115             try 
1116                 $words = (int)($this->size / 2);
1117                 $bs = new QRbitstream();
1118                 
1119                 $bs->appendNum(4, 0x02);
1120                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
1121 
1122                 for($i=0; $i<$words; $i++) 
1123                     $val  = (int)QRinput::lookAnTable(ord($this->data[$i*2  ])) * 45;
1124                     $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));
1125 
1126                     $bs->appendNum(11, $val);
1127                 
1128 
1129                 if($this->size & 1) 
1130                     $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
1131                     $bs->appendNum(6, $val);
1132                 
1133         
1134                 $this->bstream = $bs;
1135                 return 0;
1136             
1137              catch (Exception $e) 
1138                 return -1;
1139             
1140         
1141         
1142         //----------------------------------------------------------------------
1143         public function encodeMode8($version)
1144         
1145             try 
1146                 $bs = new QRbitstream();
1147 
1148                 $bs->appendNum(4, 0x4);
1149                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
1150 
1151                 for($i=0; $i<$this->size; $i++) 
1152                     $bs->appendNum(8, ord($this->data[$i]));
1153                 
1154 
1155                 $this->bstream = $bs;
1156                 return 0;
1157             
1158              catch (Exception $e) 
1159                 return -1;
1160             
1161         
1162         
1163         //----------------------------------------------------------------------
1164         public function encodeModeKanji($version)
1165         
1166             try 
1167 
1168                 $bs = new QRbitrtream();
1169                 
1170                 $bs->appendNum(4, 0x8);
1171                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
1172 
1173                 for($i=0; $i<$this->size; $i+=2) 
1174                     $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);
1175                     if($val <= 0x9ffc) 
1176                         $val -= 0x8140;
1177                      else 
1178                         $val -= 0xc140;
1179                     
1180                     
1181                     $h = ($val >> 8) * 0xc0;
1182                     $val = ($val & 0xff) + $h;
1183 
1184                     $bs->appendNum(13, $val);
1185                 
1186 
1187                 $this->bstream = $bs;
1188                 return 0;
1189             
1190              catch (Exception $e) 
1191                 return -1;
1192             
1193         
1194 
1195         //----------------------------------------------------------------------
1196         public function encodeModeStructure()
1197         
1198             try 
1199                 $bs =  new QRbitstream();
1200                 
1201                 $bs->appendNum(4, 0x03);
1202                 $bs->appendNum(4, ord($this->data[1]) - 1);
1203                 $bs->appendNum(4, ord($this->data[0]) - 1);
1204                 $bs->appendNum(8, ord($this->data[2]));
1205 
1206                 $this->bstream = $bs;
1207                 return 0;
1208             
1209              catch (Exception $e) 
1210                 return -1;
1211             
1212         
1213         
1214         //----------------------------------------------------------------------
1215         public function estimateBitStreamSizeOfEntry($version)
1216         
1217             $bits = 0;
1218 
1219             if($version == 0) 
1220                 $version = 1;
1221 
1222             switch($this->mode) 
1223                 case QR_MODE_NUM:        $bits = QRinput::estimateBitsModeNum($this->size);    break;
1224                 case QR_MODE_AN:        $bits = QRinput::estimateBitsModeAn($this->size);    break;
1225                 case QR_MODE_8:            $bits = QRinput::estimateBitsMode8($this->size);    break;
1226                 case QR_MODE_KANJI:        $bits = QRinput::estimateBitsModeKanji($this->size);break;
1227                 case QR_MODE_STRUCTURE:    return STRUCTURE_HEADER_BITS;            
1228                 default:
1229                     return 0;
1230             
1231 
1232             $l = QRspec::lengthIndicator($this->mode, $version);
1233             $m = 1 << $l;
1234             $num = (int)(($this->size + $m - 1) / $m);
1235 
1236             $bits += $num * (4 + $l);
1237 
1238             return $bits;
1239         
1240         
1241         //----------------------------------------------------------------------
1242         public function encodeBitStream($version)
1243         
1244             try 
1245             
1246                 unset($this->bstream);
1247                 $words = QRspec::maximumWords($this->mode, $version);
1248                 
1249                 if($this->size > $words) 
1250                 
1251                     $st1 = new QRinputItem($this->mode, $words, $this->data);
1252                     $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
1253 
1254                     $st1->encodeBitStream($version);
1255                     $st2->encodeBitStream($version);
1256                     
1257                     $this->bstream = new QRbitstream();
1258                     $this->bstream->append($st1->bstream);
1259                     $this->bstream->append($st2->bstream);
1260                     
1261                     unset($st1);
1262                     unset($st2);
1263                     
1264                  else 
1265                     
1266                     $ret = 0;
1267                     
1268                     switch($this->mode) 
1269                         case QR_MODE_NUM:        $ret = $this->encodeModeNum($version);    break;
1270                         case QR_MODE_AN:        $ret = $this->encodeModeAn($version);    break;
1271                         case QR_MODE_8:            $ret = $this->encodeMode8($version);    break;
1272                         case QR_MODE_KANJI:        $ret = $this->encodeModeKanji($version);break;
1273                         case QR_MODE_STRUCTURE:    $ret = $this->encodeModeStructure();    break;
1274                         
1275                         default:
1276                             break;
1277                     
1278                     
1279                     if($ret < 0)
1280                         return -1;
1281                 
1282 
1283                 return $this->bstream->size();
1284             
1285              catch (Exception $e) 
1286                 return -1;
1287             
1288         
1289     ;
1290     
1291     //##########################################################################
1292 
1293     class QRinput 
1294 
1295         public $items;
1296         
1297         private $version;
1298         private $level;
1299         
1300         //----------------------------------------------------------------------
1301         public function __construct($version = 0, $level = QR_ECLEVEL_L)
1302         
1303             if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) 
1304                 throw new Exception(‘Invalid version no‘);
1305                 return NULL;
1306             
1307             
1308             $this->version = $version;
1309             $this->level = $level;
1310         
1311         
1312         //----------------------------------------------------------------------
1313         public function getVersion()
1314         
1315             return $this->version;
1316         
1317         
1318         //----------------------------------------------------------------------
1319         public function setVersion($version)
1320         
1321             if($version < 0 || $version > QRSPEC_VERSION_MAX) 
1322                 throw new Exception(‘Invalid version no‘);
1323                 return -1;
1324             
1325 
1326             $this->version = $version;
1327 
1328             return 0;
1329         
1330         
1331         //----------------------------------------------------------------------
1332         public function getErrorCorrectionLevel()
1333         
1334             return $this->level;
1335         
1336 
1337         //----------------------------------------------------------------------
1338         public function setErrorCorrectionLevel($level)
1339         
1340             if($level > QR_ECLEVEL_H) 
1341                 throw new Exception(‘Invalid ECLEVEL‘);
1342                 return -1;
1343             
1344 
1345             $this->level = $level;
1346 
1347             return 0;
1348         
1349         
1350         //----------------------------------------------------------------------
1351         public function appendEntry(QRinputItem $entry)
1352         
1353             $this->items[] = $entry;
1354         
1355         
1356         //----------------------------------------------------------------------
1357         public function append($mode, $size, $data)
1358         
1359             try 
1360                 $entry = new QRinputItem($mode, $size, $data);
1361                 $this->items[] = $entry;
1362                 return 0;
1363              catch (Exception $e) 
1364                 return -1;
1365             
1366         
1367         
1368         //----------------------------------------------------------------------
1369         
1370         public function insertStructuredAppendHeader($size, $index, $parity)
1371         
1372             if( $size > MAX_STRUCTURED_SYMBOLS ) 
1373                 throw new Exception(‘insertStructuredAppendHeader wrong size‘);
1374             
1375             
1376             if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) 
1377                 throw new Exception(‘insertStructuredAppendHeader wrong index‘);
1378             
1379 
1380             $buf = array($size, $index, $parity);
1381             
1382             try 
1383                 $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
1384                 array_unshift($this->items, $entry);
1385                 return 0;
1386              catch (Exception $e) 
1387                 return -1;
1388             
1389         
1390 
1391         //----------------------------------------------------------------------
1392         public function calcParity()
1393         
1394             $parity = 0;
1395             
1396             foreach($this->items as $item) 
1397                 if($item->mode != QR_MODE_STRUCTURE) 
1398                     for($i=$item->size-1; $i>=0; $i--) 
1399                         $parity ^= $item->data[$i];
1400                     
1401                 
1402             
1403 
1404             return $parity;
1405         
1406         
1407         //----------------------------------------------------------------------
1408         public static function checkModeNum($size, $data)
1409         
1410             for($i=0; $i<$size; $i++) 
1411                 if((ord($data[$i]) < ord(‘0‘)) || (ord($data[$i]) > ord(‘9‘)))
1412                     return false;
1413                 
1414             
1415 
1416             return true;
1417         
1418 
1419         //----------------------------------------------------------------------
1420         public static function estimateBitsModeNum($size)
1421         
1422             $w = (int)$size / 3;
1423             $bits = $w * 10;
1424             
1425             switch($size - $w * 3) 
1426                 case 1:
1427                     $bits += 4;
1428                     break;
1429                 case 2:
1430                     $bits += 7;
1431                     break;
1432                 default:
1433                     break;
1434             
1435 
1436             return $bits;
1437         
1438         
1439         //----------------------------------------------------------------------
1440         public static $anTable = array(
1441             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1442             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1443             36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
1444              0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,
1445             -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1446             25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
1447             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1448             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1449         );
1450         
1451         //----------------------------------------------------------------------
1452         public static function lookAnTable($c)
1453         
1454             return (($c > 127)?-1:self::$anTable[$c]);
1455         
1456         
1457         //----------------------------------------------------------------------
1458         public static function checkModeAn($size, $data)
1459         
1460             for($i=0; $i<$size; $i++) 
1461                 if (self::lookAnTable(ord($data[$i])) == -1) 
1462                     return false;
1463                 
1464             
1465 
1466             return true;
1467         
1468         
1469         //----------------------------------------------------------------------
1470         public static function estimateBitsModeAn($size)
1471         
1472             $w = (int)($size / 2);
1473             $bits = $w * 11;
1474             
1475             if($size & 1) 
1476                 $bits += 6;
1477             
1478 
1479             return $bits;
1480         
1481     
1482         //----------------------------------------------------------------------
1483         public static function estimateBitsMode8($size)
1484         
1485             return $size * 8;
1486         
1487         
1488         //----------------------------------------------------------------------
1489         public function estimateBitsModeKanji($size)
1490         
1491             return (int)(($size / 2) * 13);
1492         
1493         
1494         //----------------------------------------------------------------------
1495         public static function checkModeKanji($size, $data)
1496         
1497             if($size & 1)
1498                 return false;
1499 
1500             for($i=0; $i<$size; $i+=2) 
1501                 $val = (ord($data[$i]) << 8) | ord($data[$i+1]);
1502                 if( $val < 0x8140 
1503                 || ($val > 0x9ffc && $val < 0xe040) 
1504                 || $val > 0xebbf) 
1505                     return false;
1506                 
1507             
1508 
1509             return true;
1510         
1511 
1512         /***********************************************************************
1513          * Validation
1514          **********************************************************************/
1515 
1516         public static function check($mode, $size, $data)
1517         
1518             if($size <= 0) 
1519                 return false;
1520 
1521             switch($mode) 
1522                 case QR_MODE_NUM:       return self::checkModeNum($size, $data);   break;
1523                 case QR_MODE_AN:        return self::checkModeAn($size, $data);    break;
1524                 case QR_MODE_KANJI:     return self::checkModeKanji($size, $data); break;
1525                 case QR_MODE_8:         return true; break;
1526                 case QR_MODE_STRUCTURE: return true; break;
1527                 
1528                 default:
1529                     break;
1530             
1531 
1532             return false;
1533         
1534         
1535         
1536         //----------------------------------------------------------------------
1537         public function estimateBitStreamSize($version)
1538         
1539             $bits = 0;
1540 
1541             foreach($this->items as $item) 
1542                 $bits += $item->estimateBitStreamSizeOfEntry($version);
1543             
1544 
1545             return $bits;
1546         
1547         
1548         //----------------------------------------------------------------------
1549         public function estimateVersion()
1550         
1551             $version = 0;
1552             $prev = 0;
1553             do 
1554                 $prev = $version;
1555                 $bits = $this->estimateBitStreamSize($prev);
1556                 $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
1557                 if ($version < 0) 
1558                     return -1;
1559                 
1560              while ($version > $prev);
1561 
1562             return $version;
1563         
1564         
1565         //----------------------------------------------------------------------
1566         public static function lengthOfCode($mode, $version, $bits)
1567         
1568             $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
1569             switch($mode) 
1570                 case QR_MODE_NUM:
1571                     $chunks = (int)($payload / 10);
1572                     $remain = $payload - $chunks * 10;
1573                     $size = $chunks * 3;
1574                     if($remain >= 7) 
1575                         $size += 2;
1576                      else if($remain >= 4) 
1577                         $size += 1;
1578                     
1579                     break;
1580                 case QR_MODE_AN:
1581                     $chunks = (int)($payload / 11);
1582                     $remain = $payload - $chunks * 11;
1583                     $size = $chunks * 2;
1584                     if($remain >= 6) 
1585                         $size++;
1586                     break;
1587                 case QR_MODE_8:
1588                     $size = (int)($payload / 8);
1589                     break;
1590                 case QR_MODE_KANJI:
1591                     $size = (int)(($payload / 13) * 2);
1592                     break;
1593                 case QR_MODE_STRUCTURE:
1594                     $size = (int)($payload / 8);
1595                     break;
1596                 default:
1597                     $size = 0;
1598                     break;
1599             
1600             
1601             $maxsize = QRspec::maximumWords($mode, $version);
1602             if($size < 0) $size = 0;
1603             if($size > $maxsize) $size = $maxsize;
1604 
1605             return $size;
1606         
1607         
1608         //----------------------------------------------------------------------
1609         public function createBitStream()
1610         
1611             $total = 0;
1612 
1613             foreach($this->items as $item) 
1614                 $bits = $item->encodeBitStream($this->version);
1615                 
1616                 if($bits < 0) 
1617                     return -1;
1618                     
1619                 $total += $bits;
1620             
1621 
1622             return $total;
1623         
1624         
1625         //----------------------------------------------------------------------
1626         public function convertData()
1627         
1628             $ver = $this->estimateVersion();
1629             if($ver > $this->getVersion()) 
1630                 $this->setVersion($ver);
1631             
1632 
1633             for(;;) 
1634                 $bits = $this->createBitStream();
1635                 
1636                 if($bits < 0) 
1637                     return -1;
1638                     
1639                 $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);
1640                 if($ver < 0) 
1641                     throw new Exception(‘WRONG VERSION‘);
1642                     return -1;
1643                  else if($ver > $this->getVersion()) 
1644                     $this->setVersion($ver);
1645                  else 
1646                     break;
1647                 
1648             
1649 
1650             return 0;
1651         
1652         
1653         //----------------------------------------------------------------------
1654         public function appendPaddingBit(&$bstream)
1655         
1656             $bits = $bstream->size();
1657             $maxwords = QRspec::getDataLength($this->version, $this->level);
1658             $maxbits = $maxwords * 8;
1659 
1660             if ($maxbits == $bits) 
1661                 return 0;
1662             
1663 
1664             if ($maxbits - $bits < 5) 
1665                 return $bstream->appendNum($maxbits - $bits, 0);
1666             
1667 
1668             $bits += 4;
1669             $words = (int)(($bits + 7) / 8);
1670 
1671             $padding = new QRbitstream();
1672             $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
1673             
1674             if($ret < 0) 
1675                 return $ret;
1676 
1677             $padlen = $maxwords - $words;
1678             
1679             if($padlen > 0) 
1680                 
1681                 $padbuf = array();
1682                 for($i=0; $i<$padlen; $i++) 
1683                     $padbuf[$i] = ($i&1)?0x11:0xec;
1684                 
1685                 
1686                 $ret = $padding->appendBytes($padlen, $padbuf);
1687                 
1688                 if($ret < 0)
1689                     return $ret;
1690                 
1691             
1692 
1693             $ret = $bstream->append($padding);
1694             
1695             return $ret;
1696         
1697 
1698         //----------------------------------------------------------------------
1699         public function mergeBitStream()
1700         
1701             if($this->convertData() < 0) 
1702                 return null;
1703             
1704 
1705             $bstream = new QRbitstream();
1706             
1707             foreach($this->items as $item) 
1708                 $ret = $bstream->append($item->bstream);
1709                 if($ret < 0) 
1710                     return null;
1711                 
1712             
1713 
1714             return $bstream;
1715         
1716 
1717         //----------------------------------------------------------------------
1718         public function getBitStream()
1719         
1720 
1721             $bstream = $this->mergeBitStream();
1722             
1723             if($bstream == null) 
1724                 return null;
1725             
1726             
1727             $ret = $this->appendPaddingBit($bstream);
1728             if($ret < 0) 
1729                 return null;
1730             
1731 
1732             return $bstream;
1733         
1734         
1735         //----------------------------------------------------------------------
1736         public function getByteStream()
1737         
1738             $bstream = $this->getBitStream();
1739             if($bstream == null) 
1740                 return null;
1741             
1742             
1743             return $bstream->toByte();
1744         
1745     
1746         
1747         
1748     
1749 
1750 
1751 
1752 //---- qrbitstream.php -----------------------------
1753 
1754 
1755 
1756 
1757 /*
1758  * PHP QR Code encoder
1759  *
1760  * Bitstream class
1761  * 比特流类
1762  *
1763  * Based on libqrencode C library distributed under LGPL 2.1
1764  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1765  *
1766  * PHP QR Code is distributed under LGPL 3
1767  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1768  *
1769  * This library is free software; you can redistribute it and/or
1770  * modify it under the terms of the GNU Lesser General Public
1771  * License as published by the Free Software Foundation; either
1772  * version 3 of the License, or any later version.
1773  *
1774  * This library is distributed in the hope that it will be useful,
1775  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1776  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1777  * Lesser General Public License for more details.
1778  *
1779  * You should have received a copy of the GNU Lesser General Public
1780  * License along with this library; if not, write to the Free Software
1781  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1782  */
1783      
1784     class QRbitstream 
1785     
1786         public $data = array();
1787         
1788         //----------------------------------------------------------------------
1789         public function size()
1790         
1791             return count($this->data);
1792         
1793         
1794         //----------------------------------------------------------------------
1795         public function allocate($setLength)
1796         
1797             $this->data = array_fill(0, $setLength, 0);
1798             return 0;
1799         
1800     
1801         //----------------------------------------------------------------------
1802         public static function newFromNum($bits, $num)
1803         
1804             $bstream = new QRbitstream();
1805             $bstream->allocate($bits);
1806             
1807             $mask = 1 << ($bits - 1);
1808             for($i=0; $i<$bits; $i++) 
1809                 if($num & $mask) 
1810                     $bstream->data[$i] = 1;
1811                  else 
1812                     $bstream->data[$i] = 0;
1813                 
1814                 $mask = $mask >> 1;
1815             
1816 
1817             return $bstream;
1818         
1819         
1820         //----------------------------------------------------------------------
1821         public static function newFromBytes($size, $data)
1822         
1823             $bstream = new QRbitstream();
1824             $bstream->allocate($size * 8);
1825             $p=0;
1826 
1827             for($i=0; $i<$size; $i++) 
1828                 $mask = 0x80;
1829                 for($j=0; $j<8; $j++) 
1830                     if($data[$i] & $mask) 
1831                         $bstream->data[$p] = 1;
1832                      else 
1833                         $bstream->data[$p] = 0;
1834                     
1835                     $p++;
1836                     $mask = $mask >> 1;
1837                 
1838             
1839 
1840             return $bstream;
1841         
1842         
1843         //----------------------------------------------------------------------
1844         public function append(QRbitstream $arg)
1845         
1846             if (is_null($arg)) 
1847                 return -1;
1848             
1849             
1850             if($arg->size() == 0) 
1851                 return 0;
1852             
1853             
1854             if($this->size() == 0) 
1855                 $this->data = $arg->data;
1856                 return 0;
1857             
1858             
1859             $this->data = array_values(array_merge($this->data, $arg->data));
1860 
1861             return 0;
1862         
1863         
1864         //----------------------------------------------------------------------
1865         public function appendNum($bits, $num)
1866         
1867             if ($bits == 0) 
1868                 return 0;
1869 
1870             $b = QRbitstream::newFromNum($bits, $num);
1871             
1872             if(is_null($b))
1873                 return -1;
1874 
1875             $ret = $this->append($b);
1876             unset($b);
1877 
1878             return $ret;
1879         
1880 
1881         //----------------------------------------------------------------------
1882         public function appendBytes($size, $data)
1883         
1884             if ($size == 0) 
1885                 return 0;
1886 
1887             $b = QRbitstream::newFromBytes($size, $data);
1888             
1889             if(is_null($b))
1890                 return -1;
1891 
1892             $ret = $this->append($b);
1893             unset($b);
1894 
1895             return $ret;
1896         
1897         
1898         //----------------------------------------------------------------------
1899         public function toByte()
1900         
1901         
1902             $size = $this->size();
1903 
1904             if($size == 0) 
1905                 return array();
1906             
1907             
1908             $data = array_fill(0, (int)(($size + 7) / 8), 0);
1909             $bytes = (int)($size / 8);
1910 
1911             $p = 0;
1912             
1913             for($i=0; $i<$bytes; $i++) 
1914                 $v = 0;
1915                 for($j=0; $j<8; $j++) 
1916                     $v = $v << 1;
1917                     $v |= $this->data[$p];
1918                     $p++;
1919                 
1920                 $data[$i] = $v;
1921             
1922             
1923             if($size & 7) 
1924                 $v = 0;
1925                 for($j=0; $j<($size & 7); $j++) 
1926                     $v = $v << 1;
1927                     $v |= $this->data[$p];
1928                     $p++;
1929                 
1930                 $data[$bytes] = $v;
1931             
1932 
1933             return $data;
1934         
1935 
1936     
1937 
1938 
1939 
1940 
1941 //---- qrsplit.php -----------------------------
1942 
1943 
1944 
1945 
1946 /*
1947  * PHP QR Code encoder
1948  *
1949  * Input splitting classes
1950  * 输入分割类
1951  *
1952  * Based on libqrencode C library distributed under LGPL 2.1
1953  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1954  *
1955  * PHP QR Code is distributed under LGPL 3
1956  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1957  *
1958  * The following data / specifications are taken from
1959  * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
1960  *  or
1961  * "Automatic identification and data capture techniques -- 
1962  *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
1963  *
1964  * This library is free software; you can redistribute it and/or
1965  * modify it under the terms of the GNU Lesser General Public
1966  * License as published by the Free Software Foundation; either
1967  * version 3 of the License, or any later version.
1968  *
1969  * This library is distributed in the hope that it will be useful,
1970  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1971  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1972  * Lesser General Public License for more details.
1973  *
1974  * You should have received a copy of the GNU Lesser General Public
1975  * License along with this library; if not, write to the Free Software
1976  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1977  */
1978     class QRsplit 
1979 
1980         public $dataStr = ‘‘;
1981         public $input;
1982         public $modeHint;
1983 
1984         //----------------------------------------------------------------------
1985         public function __construct($dataStr, $input, $modeHint) 
1986         
1987             $this->dataStr  = $dataStr;
1988             $this->input    = $input;
1989             $this->modeHint = $modeHint;
1990         
1991         
1992         //----------------------------------------------------------------------
1993         public static function isdigitat($str, $pos)
1994             
1995             if ($pos >= strlen($str))
1996                 return false;
1997             
1998             return ((ord($str[$pos]) >= ord(‘0‘))&&(ord($str[$pos]) <= ord(‘9‘)));
1999         
2000         
2001         //----------------------------------------------------------------------
2002         public static function isalnumat($str, $pos)
2003         
2004             if ($pos >= strlen($str))
2005                 return false;
2006                 
2007             return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
2008         
2009 
2010         //----------------------------------------------------------------------
2011         public function identifyMode($pos)
2012         
2013             if ($pos >= strlen($this->dataStr)) 
2014                 return QR_MODE_NUL;
2015                 
2016             $c = $this->dataStr[$pos];
2017             
2018             if(self::isdigitat($this->dataStr, $pos)) 
2019                 return QR_MODE_NUM;
2020              else if(self::isalnumat($this->dataStr, $pos)) 
2021                 return QR_MODE_AN;
2022              else if($this->modeHint == QR_MODE_KANJI) 
2023             
2024                 if ($pos+1 < strlen($this->dataStr)) 
2025                 
2026                     $d = $this->dataStr[$pos+1];
2027                     $word = (ord($c) << 8) | ord($d);
2028                     if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) 
2029                         return QR_MODE_KANJI;
2030                     
2031                 
2032             
2033 
2034             return QR_MODE_8;
2035          
2036         
2037         //----------------------------------------------------------------------
2038         public function eatNum()
2039         
2040             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2041 
2042             $p = 0;
2043             while(self::isdigitat($this->dataStr, $p)) 
2044                 $p++;
2045             
2046             
2047             $run = $p;
2048             $mode = $this->identifyMode($p);
2049             
2050             if($mode == QR_MODE_8) 
2051                 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
2052                      + QRinput::estimateBitsMode8(1)         // + 4 + l8
2053                      - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
2054                 if($dif > 0) 
2055                     return $this->eat8();
2056                 
2057             
2058             if($mode == QR_MODE_AN) 
2059                 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
2060                      + QRinput::estimateBitsModeAn(1)        // + 4 + la
2061                      - QRinput::estimateBitsModeAn($run + 1);// - 4 - la
2062                 if($dif > 0) 
2063                     return $this->eatAn();
2064                 
2065             
2066             
2067             $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
2068             if($ret < 0)
2069                 return -1;
2070 
2071             return $run;
2072         
2073         
2074         //----------------------------------------------------------------------
2075         public function eatAn()
2076         
2077             $la = QRspec::lengthIndicator(QR_MODE_AN,  $this->input->getVersion());
2078             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2079 
2080             $p = 0;
2081             
2082             while(self::isalnumat($this->dataStr, $p)) 
2083                 if(self::isdigitat($this->dataStr, $p)) 
2084                     $q = $p;
2085                     while(self::isdigitat($this->dataStr, $q)) 
2086                         $q++;
2087                     
2088                     
2089                     $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
2090                          + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
2091                          - QRinput::estimateBitsModeAn($q); // - 4 - la
2092                          
2093                     if($dif < 0) 
2094                         break;
2095                      else 
2096                         $p = $q;
2097                     
2098                  else 
2099                     $p++;
2100                 
2101             
2102 
2103             $run = $p;
2104 
2105             if(!self::isalnumat($this->dataStr, $p)) 
2106                 $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
2107                      + QRinput::estimateBitsMode8(1) // + 4 + l8
2108                       - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
2109                 if($dif > 0) 
2110                     return $this->eat8();
2111                 
2112             
2113 
2114             $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
2115             if($ret < 0)
2116                 return -1;
2117 
2118             return $run;
2119         
2120         
2121         //----------------------------------------------------------------------
2122         public function eatKanji()
2123         
2124             $p = 0;
2125             
2126             while($this->identifyMode($p) == QR_MODE_KANJI) 
2127                 $p += 2;
2128             
2129             
2130             $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
2131             if($ret < 0)
2132                 return -1;
2133 
2134             return $run;
2135         
2136 
2137         //----------------------------------------------------------------------
2138         public function eat8()
2139         
2140             $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
2141             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2142 
2143             $p = 1;
2144             $dataStrLen = strlen($this->dataStr);
2145             
2146             while($p < $dataStrLen) 
2147                 
2148                 $mode = $this->identifyMode($p);
2149                 if($mode == QR_MODE_KANJI) 
2150                     break;
2151                 
2152                 if($mode == QR_MODE_NUM) 
2153                     $q = $p;
2154                     while(self::isdigitat($this->dataStr, $q)) 
2155                         $q++;
2156                     
2157                     $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
2158                          + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
2159                          - QRinput::estimateBitsMode8($q); // - 4 - l8
2160                     if($dif < 0) 
2161                         break;
2162                      else 
2163                         $p = $q;
2164                     
2165                  else if($mode == QR_MODE_AN) 
2166                     $q = $p;
2167                     while(self::isalnumat($this->dataStr, $q)) 
2168                         $q++;
2169                     
2170                     $dif = QRinput::estimateBitsMode8($p)  // + 4 + l8
2171                          + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
2172                          - QRinput::estimateBitsMode8($q); // - 4 - l8
2173                     if($dif < 0) 
2174                         break;
2175                      else 
2176                         $p = $q;
2177                     
2178                  else 
2179                     $p++;
2180                 
2181             
2182 
2183             $run = $p;
2184             $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
2185             
2186             if($ret < 0)
2187                 return -1;
2188 
2189             return $run;
2190         
2191 
2192         //----------------------------------------------------------------------
2193         public function splitString()
2194         
2195             while (strlen($this->dataStr) > 0)
2196             
2197                 if($this->dataStr == ‘‘)
2198                     return 0;
2199 
2200                 $mode = $this->identifyMode(0);
2201                 
2202                 switch ($mode) 
2203                     case QR_MODE_NUM: $length = $this->eatNum(); break;
2204                     case QR_MODE_AN:  $length = $this->eatAn(); break;
2205                     case QR_MODE_KANJI:
2206                         if ($hint == QR_MODE_KANJI)
2207                                 $length = $this->eatKanji();
2208                         else    $length = $this->eat8();
2209                         break;
2210                     default: $length = $this->eat8(); break;
2211                 
2212                 
2213 
2214                 if($length == 0) return 0;
2215                 if($length < 0)  return -1;
2216                 
2217                 $this->dataStr = substr($this->dataStr, $length);
2218             
2219         
2220 
2221         //----------------------------------------------------------------------
2222         public function toUpper()
2223         
2224             $stringLen = strlen($this->dataStr);
2225             $p = 0;
2226             
2227             while ($p<$stringLen) 
2228                 $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);
2229                 if($mode == QR_MODE_KANJI) 
2230                     $p += 2;
2231                  else 
2232                     if (ord($this->dataStr[$p]) >= ord(‘a‘) && ord($this->dataStr[$p]) <= ord(‘z‘)) 
2233                         $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
2234                     
2235                     $p++;
2236                 
2237             
2238 
2239             return $this->dataStr;
2240         
2241 
2242         //----------------------------------------------------------------------
2243         public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
2244         
2245             if(is_null($string) || $string == ‘\0‘ || $string == ‘‘) 
2246                 throw new Exception(‘empty string!!!‘);
2247             
2248 
2249             $split = new QRsplit($string, $input, $modeHint);
2250             
2251             if(!$casesensitive)
2252                 $split->toUpper();
2253                 
2254             return $split->splitString();
2255         
2256     
2257 
2258 
2259 
2260 //---- qrrscode.php -----------------------------
2261 
2262 
2263 
2264 
2265 /*
2266  * PHP QR Code encoder
2267  *
2268  * Reed-Solomon error correction support
2269  * 里德所罗门错误纠正支持
2270  * 
2271  * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
2272  * (libfec is released under the GNU Lesser General Public License.)
2273  *
2274  * Based on libqrencode C library distributed under LGPL 2.1
2275  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2276  *
2277  * PHP QR Code is distributed under LGPL 3
2278  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2279  *
2280  * This library is free software; you can redistribute it and/or
2281  * modify it under the terms of the GNU Lesser General Public
2282  * License as published by the Free Software Foundation; either
2283  * version 3 of the License, or any later version.
2284  *
2285  * This library is distributed in the hope that it will be useful,
2286  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2287  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2288  * Lesser General Public License for more details.
2289  *
2290  * You should have received a copy of the GNU Lesser General Public
2291  * License along with this library; if not, write to the Free Software
2292  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2293  */
2294  
2295     class QRrsItem 
2296     
2297         public $mm;                  // Bits per symbol 
2298         public $nn;                  // Symbols per block (= (1<<mm)-1) 
2299         public $alpha_to = array();  // log lookup table 
2300         public $index_of = array();  // Antilog lookup table 
2301         public $genpoly = array();   // Generator polynomial 
2302         public $nroots;              // Number of generator roots = number of parity symbols 
2303         public $fcr;                 // First consecutive root, index form 
2304         public $prim;                // Primitive element, index form 
2305         public $iprim;               // prim-th root of 1, index form 
2306         public $pad;                 // Padding bytes in shortened block 
2307         public $gfpoly;
2308     
2309         //----------------------------------------------------------------------
2310         public function modnn($x)
2311         
2312             while ($x >= $this->nn) 
2313                 $x -= $this->nn;
2314                 $x = ($x >> $this->mm) + ($x & $this->nn);
2315             
2316             
2317             return $x;
2318         
2319         
2320         //----------------------------------------------------------------------
2321         public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2322         
2323             // Common code for intializing a Reed-Solomon control block (char or int symbols)
2324             // Copyright 2004 Phil Karn, KA9Q
2325             // May be used under the terms of the GNU Lesser General Public License (LGPL)
2326 
2327             $rs = null;
2328             
2329             // Check parameter ranges
2330             if($symsize < 0 || $symsize > 8)                     return $rs;
2331             if($fcr < 0 || $fcr >= (1<<$symsize))                return $rs;
2332             if($prim <= 0 || $prim >= (1<<$symsize))             return $rs;
2333             if($nroots < 0 || $nroots >= (1<<$symsize))          return $rs; // Can‘t have more roots than symbol values!
2334             if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
2335 
2336             $rs = new QRrsItem();
2337             $rs->mm = $symsize;
2338             $rs->nn = (1<<$symsize)-1;
2339             $rs->pad = $pad;
2340 
2341             $rs->alpha_to = array_fill(0, $rs->nn+1, 0);
2342             $rs->index_of = array_fill(0, $rs->nn+1, 0);
2343           
2344             // PHP style macro replacement ;)
2345             $NN =& $rs->nn;
2346             $A0 =& $NN;
2347             
2348             // Generate Galois field lookup tables
2349             $rs->index_of[0] = $A0; // log(zero) = -inf
2350             $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
2351             $sr = 1;
2352           
2353             for($i=0; $i<$rs->nn; $i++) 
2354                 $rs->index_of[$sr] = $i;
2355                 $rs->alpha_to[$i] = $sr;
2356                 $sr <<= 1;
2357                 if($sr & (1<<$symsize)) 
2358                     $sr ^= $gfpoly;
2359                 
2360                 $sr &= $rs->nn;
2361             
2362             
2363             if($sr != 1)
2364                 // field generator polynomial is not primitive!
2365                 $rs = NULL;
2366                 return $rs;
2367             
2368 
2369             /* Form RS code generator polynomial from its roots */
2370             $rs->genpoly = array_fill(0, $nroots+1, 0);
2371         
2372             $rs->fcr = $fcr;
2373             $rs->prim = $prim;
2374             $rs->nroots = $nroots;
2375             $rs->gfpoly = $gfpoly;
2376 
2377             /* Find prim-th root of 1, used in decoding */
2378             for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)
2379             ; // intentional empty-body loop!
2380             
2381             $rs->iprim = (int)($iprim / $prim);
2382             $rs->genpoly[0] = 1;
2383             
2384             for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) 
2385                 $rs->genpoly[$i+1] = 1;
2386 
2387                 // Multiply rs->genpoly[] by  @**(root + x)
2388                 for ($j = $i; $j > 0; $j--) 
2389                     if ($rs->genpoly[$j] != 0) 
2390                         $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
2391                      else 
2392                         $rs->genpoly[$j] = $rs->genpoly[$j-1];
2393                     
2394                 
2395                 // rs->genpoly[0] can never be zero
2396                 $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
2397             
2398             
2399             // convert rs->genpoly[] to index form for quicker encoding
2400             for ($i = 0; $i <= $nroots; $i++)
2401                 $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
2402 
2403             return $rs;
2404         
2405         
2406         //----------------------------------------------------------------------
2407         public function encode_rs_char($data, &$parity)
2408         
2409             $MM       =& $this->mm;
2410             $NN       =& $this->nn;
2411             $ALPHA_TO =& $this->alpha_to;
2412             $INDEX_OF =& $this->index_of;
2413             $GENPOLY  =& $this->genpoly;
2414             $NROOTS   =& $this->nroots;
2415             $FCR      =& $this->fcr;
2416             $PRIM     =& $this->prim;
2417             $IPRIM    =& $this->iprim;
2418             $PAD      =& $this->pad;
2419             $A0       =& $NN;
2420 
2421             $parity = array_fill(0, $NROOTS, 0);
2422 
2423             for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) 
2424                 
2425                 $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
2426                 if($feedback != $A0)       
2427                     // feedback term is non-zero
2428             
2429                     // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
2430                     // always be for the polynomials constructed by init_rs()
2431                     $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
2432             
2433                     for($j=1;$j<$NROOTS;$j++) 
2434                         $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];
2435                     
2436                 
2437                 
2438                 // Shift 
2439                 array_shift($parity);
2440                 if($feedback != $A0) 
2441                     array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
2442                  else 
2443                     array_push($parity, 0);
2444                 
2445             
2446         
2447     
2448     
2449     //##########################################################################
2450     
2451     class QRrs 
2452     
2453         public static $items = array();
2454         
2455         //----------------------------------------------------------------------
2456         public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2457         
2458             foreach(self::$items as $rs) 
2459                 if($rs->pad != $pad)       continue;
2460                 if($rs->nroots != $nroots) continue;
2461                 if($rs->mm != $symsize)    continue;
2462                 if($rs->gfpoly != $gfpoly) continue;
2463                 if($rs->fcr != $fcr)       continue;
2464                 if($rs->prim != $prim)     continue;
2465 
2466                 return $rs;
2467             
2468 
2469             $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
2470             array_unshift(self::$items, $rs);
2471 
2472             return $rs;
2473         
2474     
2475 
2476 
2477 
2478 //---- qrmask.php -----------------------------
2479 
2480 
2481 
2482 
2483 /*
2484  * PHP QR Code encoder
2485  *
2486  * Masking
2487  * 屏蔽
2488  *
2489  * Based on libqrencode C library distributed under LGPL 2.1
2490  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2491  *
2492  * PHP QR Code is distributed under LGPL 3
2493  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2494  *
2495  * This library is free software; you can redistribute it and/or
2496  * modify it under the terms of the GNU Lesser General Public
2497  * License as published by the Free Software Foundation; either
2498  * version 3 of the License, or any later version.
2499  *
2500  * This library is distributed in the hope that it will be useful,
2501  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2502  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2503  * Lesser General Public License for more details.
2504  *
2505  * You should have received a copy of the GNU Lesser General Public
2506  * License along with this library; if not, write to the Free Software
2507  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2508  */
2509  
2510     define(‘N1‘, 3);
2511     define(‘N2‘, 3);
2512     define(‘N3‘, 40);
2513     define(‘N4‘, 10);
2514 
2515     class QRmask 
2516     
2517         public $runLength = array();
2518         
2519         //----------------------------------------------------------------------
2520         public function __construct() 
2521         
2522             $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
2523         
2524         
2525         //----------------------------------------------------------------------
2526         public function writeFormatInformation($width, &$frame, $mask, $level)
2527         
2528             $blacks = 0;
2529             $format =  QRspec::getFormatInfo($mask, $level);
2530 
2531             for($i=0; $i<8; $i++) 
2532                 if($format & 1) 
2533                     $blacks += 2;
2534                     $v = 0x85;
2535                  else 
2536                     $v = 0x84;
2537                 
2538                 
2539                 $frame[8][$width - 1 - $i] = chr($v);
2540                 if($i < 6) 
2541                     $frame[$i][8] = chr($v);
2542                  else 
2543                     $frame[$i + 1][8] = chr($v);
2544                 
2545                 $format = $format >> 1;
2546             
2547             
2548             for($i=0; $i<7; $i++) 
2549                 if($format & 1) 
2550                     $blacks += 2;
2551                     $v = 0x85;
2552                  else 
2553                     $v = 0x84;
2554                 
2555                 
2556                 $frame[$width - 7 + $i][8] = chr($v);
2557                 if($i == 0) 
2558                     $frame[8][7] = chr($v);
2559                  else 
2560                     $frame[8][6 - $i] = chr($v);
2561                 
2562                 
2563                 $format = $format >> 1;
2564             
2565 
2566             return $blacks;
2567         
2568         
2569         //----------------------------------------------------------------------
2570         public function mask0($x, $y)  return ($x+$y)&1;                       
2571         public function mask1($x, $y)  return ($y&1);                          
2572         public function mask2($x, $y)  return ($x%3);                          
2573         public function mask3($x, $y)  return ($x+$y)%3;                       
2574         public function mask4($x, $y)  return (((int)($y/2))+((int)($x/3)))&1; 
2575         public function mask5($x, $y)  return (($x*$y)&1)+($x*$y)%3;           
2576         public function mask6($x, $y)  return ((($x*$y)&1)+($x*$y)%3)&1;       
2577         public function mask7($x, $y)  return ((($x*$y)%3)+(($x+$y)&1))&1;     
2578         
2579         //----------------------------------------------------------------------
2580         private function generateMaskNo($maskNo, $width, $frame)
2581         
2582             $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
2583             
2584             for($y=0; $y<$width; $y++) 
2585                 for($x=0; $x<$width; $x++) 
2586                     if(ord($frame[$y][$x]) & 0x80) 
2587                         $bitMask[$y][$x] = 0;
2588                      else 
2589                         $maskFunc = call_user_func(array($this, ‘mask‘.$maskNo), $x, $y);
2590                         $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
2591                     
2592                     
2593                 
2594             
2595             
2596             return $bitMask;
2597         
2598         
2599         //----------------------------------------------------------------------
2600         public static function serial($bitFrame)
2601         
2602             $codeArr = array();
2603             
2604             foreach ($bitFrame as $line)
2605                 $codeArr[] = join(‘‘, $line);
2606                 
2607             return gzcompress(join("\n", $codeArr), 9);
2608         
2609         
2610         //----------------------------------------------------------------------
2611         public static function unserial($code)
2612         
2613             $codeArr = array();
2614             
2615             $codeLines = explode("\n", gzuncompress($code));
2616             foreach ($codeLines as $line)
2617                 $codeArr[] = str_split($line);
2618             
2619             return $codeArr;
2620         
2621         
2622         //----------------------------------------------------------------------
2623         public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) 
2624         
2625             $b = 0;
2626             $bitMask = array();
2627             
2628             $fileName = QR_CACHE_DIR.‘mask_‘.$maskNo.DIRECTORY_SEPARATOR.‘mask_‘.$width.‘_‘.$maskNo.‘.dat‘;
2629 
2630             if (QR_CACHEABLE) 
2631                 if (file_exists($fileName)) 
2632                     $bitMask = self::unserial(file_get_contents($fileName));
2633                  else 
2634                     $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
2635                     if (!file_exists(QR_CACHE_DIR.‘mask_‘.$maskNo))
2636                         mkdir(QR_CACHE_DIR.‘mask_‘.$maskNo);
2637                     file_put_contents($fileName, self::serial($bitMask));
2638                 
2639              else 
2640                 $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
2641             
2642 
2643             if ($maskGenOnly)
2644                 return;
2645                 
2646             $d = $s;
2647 
2648             for($y=0; $y<$width; $y++) 
2649                 for($x=0; $x<$width; $x++) 
2650                     if($bitMask[$y][$x] == 1) 
2651                         $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);
2652                     
2653                     $b += (int)(ord($d[$y][$x]) & 1);
2654                 
2655             
2656 
2657             return $b;
2658         
2659         
2660         //----------------------------------------------------------------------
2661         public function makeMask($width, $frame, $maskNo, $level)
2662         
2663             $masked = array_fill(0, $width, str_repeat("\0", $width));
2664             $this->makeMaskNo($maskNo, $width, $frame, $masked);
2665             $this->writeFormatInformation($width, $masked, $maskNo, $level);
2666        
2667             return $masked;
2668         
2669         
2670         //----------------------------------------------------------------------
2671         public function calcN1N3($length)
2672         
2673             $demerit = 0;
2674 
2675             for($i=0; $i<$length; $i++) 
2676                 
2677                 if($this->runLength[$i] >= 5) 
2678                     $demerit += (N1 + ($this->runLength[$i] - 5));
2679                 
2680                 if($i & 1) 
2681                     if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) 
2682                         $fact = (int)($this->runLength[$i] / 3);
2683                         if(($this->runLength[$i-2] == $fact) &&
2684                            ($this->runLength[$i-1] == $fact) &&
2685                            ($this->runLength[$i+1] == $fact) &&
2686                            ($this->runLength[$i+2] == $fact)) 
2687                             if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) 
2688                                 $demerit += N3;
2689                              else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) 
2690                                 $demerit += N3;
2691                             
2692                         
2693                     
2694                 
2695             
2696             return $demerit;
2697         
2698         
2699         //----------------------------------------------------------------------
2700         public function evaluateSymbol($width, $frame)
2701         
2702             $head = 0;
2703             $demerit = 0;
2704 
2705             for($y=0; $y<$width; $y++) 
2706                 $head = 0;
2707                 $this->runLength[0] = 1;
2708                 
2709                 $frameY = $frame[$y];
2710                 
2711                 if ($y>0)
2712                     $frameYM = $frame[$y-1];
2713                 
2714                 for($x=0; $x<$width; $x++) 
2715                     if(($x > 0) && ($y > 0)) 
2716                         $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
2717                         $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
2718                         
2719                         if(($b22 | ($w22 ^ 1))&1)                                                                      
2720                             $demerit += N2;
2721                         
2722                     
2723                     if(($x == 0) && (ord($frameY[$x]) & 1)) 
2724                         $this->runLength[0] = -1;
2725                         $head = 1;
2726                         $this->runLength[$head] = 1;
2727                      else if($x > 0) 
2728                         if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) 
2729                             $head++;
2730                             $this->runLength[$head] = 1;
2731                          else 
2732                             $this->runLength[$head]++;
2733                         
2734                     
2735                 
2736     
2737                 $demerit += $this->calcN1N3($head+1);
2738             
2739 
2740             for($x=0; $x<$width; $x++) 
2741                 $head = 0;
2742                 $this->runLength[0] = 1;
2743                 
2744                 for($y=0; $y<$width; $y++) 
2745                     if($y == 0 && (ord($frame[$y][$x]) & 1)) 
2746                         $this->runLength[0] = -1;
2747                         $head = 1;
2748                         $this->runLength[$head] = 1;
2749                      else if($y > 0) 
2750                         if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) 
2751                             $head++;
2752                             $this->runLength[$head] = 1;
2753                          else 
2754                             $this->runLength[$head]++;
2755                         
2756                     
2757                 
2758             
2759                 $demerit += $this->calcN1N3($head+1);
2760             
2761 
2762             return $demerit;
2763         
2764         
2765         
2766         //----------------------------------------------------------------------
2767         public function mask($width, $frame, $level)
2768         
2769             $minDemerit = PHP_INT_MAX;
2770             $bestMaskNum = 0;
2771             $bestMask = array();
2772             
2773             $checked_masks = array(0,1,2,3,4,5,6,7);
2774             
2775             if (QR_FIND_FROM_RANDOM !== false) 
2776             
2777                 $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
2778                 for ($i = 0; $i <  $howManuOut; $i++) 
2779                     $remPos = rand (0, count($checked_masks)-1);
2780                     unset($checked_masks[$remPos]);
2781                     $checked_masks = array_values($checked_masks);
2782                 
2783             
2784             
2785             
2786             $bestMask = $frame;
2787              
2788             foreach($checked_masks as $i) 
2789                 $mask = array_fill(0, $width, str_repeat("\0", $width));
2790 
2791                 $demerit = 0;
2792                 $blacks = 0;
2793                 $blacks  = $this->makeMaskNo($i, $width, $frame, $mask);
2794                 $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
2795                 $blacks  = (int)(100 * $blacks / ($width * $width));
2796                 $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);
2797                 $demerit += $this->evaluateSymbol($width, $mask);
2798                 
2799                 if($demerit < $minDemerit) 
2800                     $minDemerit = $demerit;
2801                     $bestMask = $mask;
2802                     $bestMaskNum = $i;
2803                 
2804             
2805             
2806             return $bestMask;
2807         
2808         
2809         //----------------------------------------------------------------------
2810     
2811 
2812 
2813 
2814 
2815 //---- qrencode.php -----------------------------
2816 
2817 
2818 
2819 
2820 /*
2821  * PHP QR Code encoder
2822  *
2823  * Main encoder classes.
2824  * 主要编码器类。
2825  *
2826  * Based on libqrencode C library distributed under LGPL 2.1
2827  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2828  *
2829  * PHP QR Code is distributed under LGPL 3
2830  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2831  *
2832  * This library is free software; you can redistribute it and/or
2833  * modify it under the terms of the GNU Lesser General Public
2834  * License as published by the Free Software Foundation; either
2835  * version 3 of the License, or any later version.
2836  *
2837  * This library is distributed in the hope that it will be useful,
2838  * but WITHOUT ANY WARRANTY; without even the implied warranty of
2839  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2840  * Lesser General Public License for more details.
2841  *
2842  * You should have received a copy of the GNU Lesser General Public
2843  * License along with this library; if not, write to the Free Software
2844  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2845  */
2846  
2847     class QRrsblock 
2848         public $dataLength;
2849         public $data = array();
2850         public $eccLength;
2851         public $ecc = array();
2852         
2853         public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
2854         
2855             $rs->encode_rs_char($data, $ecc);
2856         
2857             $this->dataLength = $dl;
2858             $this->data = $data;
2859             $this->eccLength = $el;
2860             $this->ecc = $ecc;
2861         
2862     ;
2863     
2864     //##########################################################################
2865 
2866     class QRrawcode 
2867         public $version;
2868         public $datacode = array();
2869         public $ecccode = array();
2870         public $blocks;
2871         public $rsblocks = array(); //of RSblock
2872         public $count;
2873         public $dataLength;
2874         public $eccLength;
2875         public $b1;
2876         
2877         //----------------------------------------------------------------------
2878         public function __construct(QRinput $input)
2879         
2880             $spec = array(0,0,0,0,0);
2881             
2882             $this->datacode = $input->getByteStream();
2883             if(is_null($this->datacode)) 
2884                 throw new Exception(‘null imput string‘);
2885             
2886 
2887             QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
2888 
2889             $this->version = $input->getVersion();
2890             $this->b1 = QRspec::rsBlockNum1($spec);
2891             $this->dataLength = QRspec::rsDataLength($spec);
2892             $this->eccLength = QRspec::rsEccLength($spec);
2893             $this->ecccode = array_fill(0, $this->eccLength, 0);
2894             $this->blocks = QRspec::rsBlockNum($spec);
2895             
2896             $ret = $this->init($spec);
2897             if($ret < 0) 
2898                 throw new Exception(‘block alloc error‘);
2899                 return null;
2900             
2901 
2902             $this->count = 0;
2903         
2904         
2905         //----------------------------------------------------------------------
2906         public function init(array $spec)
2907         
2908             $dl = QRspec::rsDataCodes1($spec);
2909             $el = QRspec::rsEccCodes1($spec);
2910             $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2911             
2912 
2913             $blockNo = 0;
2914             $dataPos = 0;
2915             $eccPos = 0;
2916             for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) 
2917                 $ecc = array_slice($this->ecccode,$eccPos);
2918                 $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el,  $ecc, $rs);
2919                 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
2920                 
2921                 $dataPos += $dl;
2922                 $eccPos += $el;
2923                 $blockNo++;
2924             
2925 
2926             if(QRspec::rsBlockNum2($spec) == 0)
2927                 return 0;
2928 
2929             $dl = QRspec::rsDataCodes2($spec);
2930             $el = QRspec::rsEccCodes2($spec);
2931             $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2932             
2933             if($rs == NULL) return -1;
2934             
2935             for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) 
2936                 $ecc = array_slice($this->ecccode,$eccPos);
2937                 $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
2938                 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
2939                 
2940                 $dataPos += $dl;
2941                 $eccPos += $el;
2942                 $blockNo++;
2943             
2944 
2945             return 0;
2946         
2947         
2948         //----------------------------------------------------------------------
2949         public function getCode()
2950         
2951             $ret;
2952 
2953             if($this->count < $this->dataLength) 
2954                 $row = $this->count % $this->blocks;
2955                 $col = $this->count / $this->blocks;
2956                 if($col >= $this->rsblocks[0]->dataLength) 
2957                     $row += $this->b1;
2958                 
2959                 $ret = $this->rsblocks[$row]->data[$col];
2960              else if($this->count < $this->dataLength + $this->eccLength) 
2961                 $row = ($this->count - $this->dataLength) % $this->blocks;
2962                 $col = ($this->count - $this->dataLength) / $this->blocks;
2963                 $ret = $this->rsblocks[$row]->ecc[$col];
2964              else 
2965                 return 0;
2966             
2967             $this->count++;
2968             
2969             return $ret;
2970         
2971     
2972 
2973     //##########################################################################
2974     
2975     class QRcode 
2976     
2977         public $version;
2978         public $width;
2979         public $data; 
2980         
2981         //----------------------------------------------------------------------
2982         public function encodeMask(QRinput $input, $mask)
2983         
2984             if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) 
2985                 throw new Exception(‘wrong version‘);
2986             
2987             if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) 
2988                 throw new Exception(‘wrong level‘);
2989             
2990 
2991             $raw = new QRrawcode($input);
2992             
2993             QRtools::markTime(‘after_raw‘);
2994             
2995             $version = $raw->version;
2996             $width = QRspec::getWidth($version);
2997             $frame = QRspec::newFrame($version);
2998             
2999             $filler = new FrameFiller($width, $frame);
3000             if(is_null($filler)) 
3001                 return NULL;
3002             
3003 
3004             // inteleaved data and ecc codes
3005             for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) 
3006                 $code = $raw->getCode();
3007                 $bit = 0x80;
3008                 for($j=0; $j<8; $j++) 
3009                     $addr = $filler->next();
3010                     $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
3011                     $bit = $bit >> 1;
3012                 
3013             
3014             
3015             QRtools::markTime(‘after_filler‘);
3016             
3017             unset($raw);
3018             
3019             // remainder bits
3020             $j = QRspec::getRemainder($version);
3021             for($i=0; $i<$j; $i++) 
3022                 $addr = $filler->next();
3023                 $filler->setFrameAt($addr, 0x02);
3024             
3025             
3026             $frame = $filler->frame;
3027             unset($filler);
3028             
3029             
3030             // masking
3031             $maskObj = new QRmask();
3032             if($mask < 0) 
3033             
3034                 if (QR_FIND_BEST_MASK) 
3035                     $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
3036                  else 
3037                     $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
3038                 
3039              else 
3040                 $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
3041             
3042             
3043             if($masked == NULL) 
3044                 return NULL;
3045             
3046             
3047             QRtools::markTime(‘after_mask‘);
3048             
3049             $this->version = $version;
3050             $this->width = $width;
3051             $this->data = $masked;
3052             
3053             return $this;
3054         
3055     
3056         //----------------------------------------------------------------------
3057         public function encodeInput(QRinput $input)
3058         
3059             return $this->encodeMask($input, -1);
3060         
3061         
3062         //----------------------------------------------------------------------
3063         public function encodeString8bit($string, $version, $level)
3064         
3065             if(string == NULL) 
3066                 throw new Exception(‘empty string!‘);
3067                 return NULL;
3068             
3069 
3070             $input = new QRinput($version, $level);
3071             if($input == NULL) return NULL;
3072 
3073             $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
3074             if($ret < 0) 
3075                 unset($input);
3076                 return NULL;
3077             
3078             return $this->encodeInput($input);
3079         
3080 
3081         //----------------------------------------------------------------------
3082         public function encodeString($string, $version, $level, $hint, $casesensitive)
3083         
3084 
3085             if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) 
3086                 throw new Exception(‘bad hint‘);
3087                 return NULL;
3088             
3089 
3090             $input = new QRinput($version, $level);
3091             if($input == NULL) return NULL;
3092 
3093             $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
3094             if($ret < 0) 
3095                 return NULL;
3096             
3097 
3098             return $this->encodeInput($input);
3099         
3100         
3101         //----------------------------------------------------------------------
3102         public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) 
3103         
3104             $enc = QRencode::factory($level, $size, $margin);
3105             return $enc->encodePNG($text, $outfile, $saveandprint=false);
3106         
3107 
3108         //----------------------------------------------------------------------
3109         public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
3110         
3111             $enc = QRencode::factory($level, $size, $margin);
3112             return $enc->encode($text, $outfile);
3113         
3114 
3115         //----------------------------------------------------------------------
3116         public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
3117         
3118             $enc = QRencode::factory($level, $size, $margin);
3119             return $enc->encodeRAW($text, $outfile);
3120         
3121     
3122     
3123     //##########################################################################
3124     
3125     class FrameFiller 
3126     
3127         public $width;
3128         public $frame;
3129         public $x;
3130         public $y;
3131         public $dir;
3132         public $bit;
3133         
3134         //----------------------------------------------------------------------
3135         public function __construct($width, &$frame)
3136         
3137             $this->width = $width;
3138             $this->frame = $frame;
3139             $this->x = $width - 1;
3140             $this->y = $width - 1;
3141             $this->dir = -1;
3142             $this->bit = -1;
3143         
3144         
3145         //----------------------------------------------------------------------
3146         public function setFrameAt($at, $val)
3147         
3148             $this->frame[$at[‘y‘]][$at[‘x‘]] = chr($val);
3149         
3150         
3151         //----------------------------------------------------------------------
3152         public function getFrameAt($at)
3153         
3154             return ord($this->frame[$at[‘y‘]][$at[‘x‘]]);
3155         
3156         
3157         //----------------------------------------------------------------------
3158         public function next()
3159         
3160             do 
3161             
3162                 if($this->bit == -1) 
3163                     $this->bit = 0;
3164                     return array(‘x‘=>$this->x, ‘y‘=>$this->y);
3165                 
3166 
3167                 $x = $this->x;
3168                 $y = $this->y;
3169                 $w = $this->width;
3170 
3171                 if($this->bit == 0) 
3172                     $x--;
3173                     $this->bit++;
3174                  else 
3175                     $x++;
3176                     $y += $this->dir;
3177                     $this->bit--;
3178                 
3179 
3180                 if($this->dir < 0) 
3181                     if($y < 0) 
3182                         $y = 0;
3183                         $x -= 2;
3184                         $this->dir = 1;
3185                         if($x == 6) 
3186                             $x--;
3187                             $y = 9;
3188                         
3189                     
3190                  else 
3191                     if($y == $w) 
3192                         $y = $w - 1;
3193                         $x -= 2;
3194                         $this->dir = -1;
3195                         if($x == 6) 
3196                             $x--;
3197                             $y -= 8;
3198                         
3199                     
3200                 
3201                 if($x < 0 || $y < 0) return null;
3202 
3203                 $this->x = $x;
3204                 $this->y = $y;
3205 
3206              while(ord($this->frame[$y][$x]) & 0x80);
3207                         
3208             return array(‘x‘=>$x, ‘y‘=>$y);
3209         
3210         
3211      ;
3212     
3213     //##########################################################################    
3214     
3215     class QRencode 
3216     
3217         public $casesensitive = true;
3218         public $eightbit = false;
3219         
3220         public $version = 0;
3221         public $size = 3;
3222         public $margin = 4;
3223         
3224         public $structured = 0; // not supported yet
3225         
3226         public $level = QR_ECLEVEL_L;
3227         public $hint = QR_MODE_8;
3228         
3229         //----------------------------------------------------------------------
3230         public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
3231         
3232             $enc = new QRencode();
3233             $enc->size = $size;
3234             $enc->margin = $margin;
3235             
3236             switch ($level.‘‘) 
3237                 case ‘0‘:
3238                 case ‘1‘:
3239                 case ‘2‘:
3240                 case ‘3‘:
3241                         $enc->level = $level;
3242                     break;
3243                 case ‘l‘:
3244                 case ‘L‘:
3245                         $enc->level = QR_ECLEVEL_L;
3246                     break;
3247                 case ‘m‘:
3248                 case ‘M‘:
3249                         $enc->level = QR_ECLEVEL_M;
3250                     break;
3251                 case ‘q‘:
3252                 case ‘Q‘:
3253                         $enc->level = QR_ECLEVEL_Q;
3254                     break;
3255                 case ‘h‘:
3256                 case ‘H‘:
3257                         $enc->level = QR_ECLEVEL_H;
3258                     break;
3259             
3260             
3261             return $enc;
3262         
3263         
3264         //----------------------------------------------------------------------
3265         public function encodeRAW($intext, $outfile = false) 
3266         
3267             $code = new QRcode();
3268 
3269             if($this->eightbit) 
3270                 $code->encodeString8bit($intext, $this->version, $this->level);
3271              else 
3272                 $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
3273             
3274             
3275             return $code->data;
3276         
3277 
3278         //----------------------------------------------------------------------
3279         public function encode($intext, $outfile = false) 
3280         
3281             $code = new QRcode();
3282 
3283             if($this->eightbit) 
3284                 $code->encodeString8bit($intext, $this->version, $this->level);
3285              else 
3286                 $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
3287             
3288             
3289             QRtools::markTime(‘after_encode‘);
3290             
3291             if ($outfile!== false) 
3292                 file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
3293              else 
3294                 return QRtools::binarize($code->data);
3295             
3296         
3297         
3298         //----------------------------------------------------------------------
3299         public function encodePNG($intext, $outfile = false,$saveandprint=false) 
3300         
3301             try 
3302             
3303                 ob_start();
3304                 $tab = $this->encode($intext);
3305                 $err = ob_get_contents();
3306                 ob_end_clean();
3307                 
3308                 if ($err != ‘‘)
3309                     QRtools::log($outfile, $err);
3310                 
3311                 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
3312                 
3313                 QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
3314             
3315              catch (Exception $e) 
3316             
3317                 QRtools::log($outfile, $e->getMessage());
3318             
3319             
3320         
3321     
View Code

使用方法:

import(‘qrcode/qrcode‘, EXTEND_PATH);
            $code = new \QRencode();
            $timess = time() . $ids;
            $imgurl = YM . ‘/uploads/qrcode/‘ . $timess . ‘.png‘;
            $code->encodePNG(YM . ‘/index/index/order/type/1/id/‘ . $ids . ‘.html‘, ‘./uploads/qrcode/‘ . $timess . ‘.png‘);
            return $this->responed(true, $imgurl);

 

以上是关于php 生成二维码的主要内容,如果未能解决你的问题,请参考以下文章

使用PHP QR Code生成二维码

使用PHP QR Code生成二维码

使用PHP QR Code生成二维码

php qrencode生成二维码

PHP 生成二维码

PHP生成二维码