検索
ホームページphp教程php手册あなたと共有する PHP QRcode クラス
あなたと共有する PHP QRcode クラスJun 13, 2016 pm 12:04 PM
definekmodephpそしてコード共有コピー親切

クラスコード:

コードをコピー コードは次のとおりです:


define('QR_MODE_NUL', -1);
define('QR_MODE_NUM', 0);
define('QR_MODE_AN', 1);
define('QR_MODE_8', 2);
define('QR_MODE_KANJI', 3);
define('QR_MODE_STRUCTURE', 4);
// エラー修正のレベル。
define('QR_ECLEVEL_L', 0);
define('QR_ECLEVEL_M', 1);
define('QR_ECLEVEL_Q', 2);
define('QR_ECLEVEL_H', 3);
// サポートされている出力形式
define('QR_FORMAT_TEXT', 0);
define('QR_FORMAT_PNG', 1);
class qrstr {
public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
$srctab[$y] = substr_replace($srctab[$y] ], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
}
}
define('QR_CACHEABLE', false); // キャッシュを使用します - ディスク読み取りは増加しますが、CPU パワーは低下し、マスクとフォーマット テンプレートがそこに保存されます
define('QR_CACHE_DIR', false); // QR_CACHEABLE === true の場合に使用
define('QR_LOG_DIR', false); // デフォルトのエラー ログ dir
define('QR_FIND_BEST_MASK', true); // true の場合、最良のマスクを推定します (仕様はデフォルトですが、非常に遅いです。 false に設定するとパフォーマンスが大幅に向上しますが、(おそらく) 最悪の品質のコードになります。
define('QR_FIND_FROM_RANDOM', 2); // false の場合、すべてをチェックしますマスクが利用可能、そうでない場合、値はマスクの数をチェックする必要があることを示し、マスク ID はランダムに取得されます。
define('QR_DEFAULT_MASK', 2) // QR_FIND_BEST_MASK === false の場合
define('QR_PNG_MAXIMUM_SIZE', 1024); ; // 許可される PNG 画像の最大幅 (ピクセル単位)、GD と PHP がそのような大きな画像を処理できるように調整します
class QRtools {
public static function binarize($frame){
$len = count ($frame);
foreach ($frame as &$frameLine) {
for($i=0; $i$frameLine[$i] = (ord ($frameLine[$i])&1)?'1':'0';
}
}
return $frame;
}
パブリック静的関数 tcpdfBarcodeArray($code, $ mode = 'QR,L', $tcPdfVersion = '4.5.037'){
$barcode_array = array();
if (!is_array($mode))
$mode =explode(', ', $mode);
$eccLevel = 'L';
if (count($mode) > 1) {
$eccLevel = $mode[1];
}
$qrTab = QRcode::text($code, false, $eccLevel);
$size = count($qrTab);
$barcode_array['num_rows'] = $size;
$barcode_array['num_cols'] = $size;
$barcode_array['bcode'] = array();
foreach ($qrTab as $line) {
$arrAdd = array();
foreach(str_split($line) as $char)
$arrAdd[] = ($char=='1')?1:0;
$barcode_array['bcode'][] = $arrAdd;
}
$barcode_array を返す;
}
パブリック静的関数 clearCache(){
self::$frames = array();
}
パブリック静的関数 buildCache(){
QRtools::markTime('before_build_cache');
$mask = 新しい QRmask();
for ($a=1; $a $frame = QRspec::newFrame($a);
if (QR_IMAGE) {
$fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
QRimage::png(self::binarize($frame), $fileName, 1, 0);
}
$width = count($frame);
$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
for ($maskNo=0; $maskNo$mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
}
QRtools::markTime('after_build_cache');
}
public static function log($outfile, $err){
if (QR_LOG_DIR !== false) {
if ($err != '') {
if ($ outfile !== false) {
file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
} else {
file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
}
}
}
}
パブリック静的関数 dumpMask($frame){
$width = count($frame);
for($y=0;$yfor($x=0;$xecho ord($frame[$ y][$x]).',';
}
}
}
パブリック静的関数 markTime($markerId){
list($usec, $sec) =explode(" ", microtime());
$time = ((float)$usec (float)$sec);
if (!isset($GLOBALS['qr_time_bench']))
$GLOBALS['qr_time_bench'] = array();
$GLOBALS['qr_time_bench'][$markerId] = $time;
}
パブリック静的関数 timeBenchmark(){
self::markTime('finish');
$lastTime = 0;
$startTime = 0;
$p = 0;
エコー '


ベンチマーク tr>
';
foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
if ($p > 0) {
echo '';
} else {
$startTime = $thisTime;
}
$p ;
$lastTime = $thisTime;
}
エコー '


till '.$markerId.': '.number_format($thisTime-$lastTime, 6).'s
合計: '.number_format($lastTime -$startTime, 6).の
';
}
}
//#################################### #####################################
QRtools::markTime('start');
define('QRSPEC_VERSION_MAX', 40);
define('QRSPEC_WIDTH_MAX', 177);
define('QRCAP_WIDTH', 0);
define('QRCAP_WORDS', 1);
define('QRCAP_REMINDER', 2);
define('QRCAP_EC', 3);
class QRspec {
public static $capacity = array(
array( 0, 0, 0, array( 0, 0, 0, 0)),
array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
array( 25, 44, 7, array( 10, 16, 22, 28)),
array( 29, 70, 7, array ( 15, 26, 36, 44))、
array( 33, 100, 7, array( 20, 36, 52, 64))、
array( 37, 134, 7, array( 26, 48) , 72, 88)), // 5
array( 41, 172, 7, array( 36, 64, 96, 112)),
array( 45, 196, 0, array( 40, 72, 108, 130))、
array( 49, 242, 0, array( 48, 88, 132, 156)),
array( 53, 292, 0, array( 60, 110, 160, 192) ),
array( 57, 346, 0, array( 72, 130, 192, 224)), //10
array( 61, 404, 0, array( 80, 150, 224, 264)) ,
array( 65, 466, 0, array( 96, 176, 260, 308)),
array( 69, 532, 0, array( 104, 198, 288, 352)),
array( 73, 581, 3, array( 120, 216, 320, 384)),
array( 77, 655, 3, array( 132, 240, 360, 432)), //15
array ( 81, 733, 3, array( 144, 280, 408, 480)),
array( 85, 815, 3, array( 168, 308, 448, 532)),
array( 89, 901 , 3, array( 180, 338, 504, 588)),
array( 93, 991, 3, array( 196, 364, 546, 650)),
array( 97, 1085, 3, array ( 224, 416, 600, 700)), //20
array(101, 1156, 4, array( 224, 442, 644, 750)),
array(105, 1258, 4, array( 252, 476, 690, 816))、
array(109, 1364, 4, array( 270, 504, 750, 900))、
array(113, 1474, 4, array( 300, 560, 810, 960)),
array(117, 1588, 4, array( 312, 588, 870, 1050)), //25
array(121, 1706, 4, array( 336, 644, 952) , 1110))、
array(125, 1828, 4, array( 360, 700, 1020, 1200)),
array(129, 1921, 3, array( 390, 728, 1050, 1260)) ,
array(133, 2051, 3, array( 420, 784, 1140, 1350)),
array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30
配列(141, 2323, 3, 配列(480, 868, 1290, 1530)),
配列(145, 2465, 3, 配列(510, 924, 1350, 1620)),
配列(149, 2611, 3, array( 540, 980, 1440, 1710)),
array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
array(157, 2876) , 0, array( 570, 1064, 1590, 1890)), //35
array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
);
public static function getDataLength($version, $level){
return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
}
public static function getECCLength($version, $level){
return self::$capacity[$version][QRCAP_EC][$level];
}
public static function getWidth($version){
return self::$capacity[$version][QRCAP_WIDTH];
}
public static function getRemainder($version){
return self::$capacity[$version][QRCAP_REMINDER];
}
public static function getMinimumVersion($size, $level){
for($i=1; $i$words = self::$capacity [$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
if($words >= $size)
return $i;
}
-1 を返す;
}
//######################################## ###########################
public static $lengthTableBits = array(
array(10, 12, 14) ,
array( 9, 11, 13),
array( 8, 16, 16),
array( 8, 10, 12)
);
public static function lengthIndicator($mode, $version){
if ($mode == QR_MODE_STRUCTURE)
return 0;
if ($version $l = 0;
} else if ($version $l = 1;
} else {
$l = 2;
}
return self::$lengthTableBits[$mode][$l];
}
public static function minimumWords($mode, $version){
if($mode == QR_MODE_STRUCTURE)
return 3;
if($version $l = 0;
} else if($version $l = 1;
} else {
$l = 2;
}
$bits = self::$lengthTableBits[$mode][$l];
$words = (1 if($mode == QR_MODE_KANJI) {
$words *= 2; // バイト数は必須です
}
return $words;
}
public static $eccTable = array(
array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
array(array ( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
array(array( 1, 0), array( 2, 0) ), array( 2, 2), array( 2, 2)), // 5
array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0))、
array(array( 2, 0)、array( 4, 0)、array( 2, 4)、array( 4, 1))、
array(array( 2, 0)、 array( 2, 2), array( 4, 2), array( 4, 2)),
array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10
array(array( 4, 0)、array( 1, 4)、array( 4, 4)、array( 3, 8))、
array(array( 2, 2)、array( 6, 2)、array( 4, 6), array( 7, 4)),
array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
array( array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15
array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
array(array( 5, 1), array( 9, 4)、array(17, 1)、array( 2, 19))、
array(array( 3, 4)、array( 3, 11)、array(17, 4)、array( 9, 16) ),
array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20
array(array( 4, 4) 、配列(17, 0)、配列(17, 6)、配列(19, 6))、
配列(配列( 2, 7)、配列(17, 0)、配列(7, 16)、配列(34, 0))、
array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
array(array( 6, 4)、配列( 6, 14)、配列(11, 16)、配列(30, 2))、
配列(配列( 8, 4)、配列( 8, 13)、配列( 7, 22) , array(22, 13)), //25
array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
array (配列( 8, 4), 配列(22, 3), 配列( 8, 26), 配列(12, 28)),
配列(配列( 3, 10), 配列( 3, 23), 配列( 4, 31), array(11, 31)),
array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
array(array(13, 3), array( 2 、29)、配列(42, 1)、配列(23, 28))、
配列(配列(17, 0)、配列(10, 23)、配列(10, 35)、配列(19, 35) ))、
array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
array(array(13, 6), array (14, 23)、配列(44, 7)、配列(59, 1))、
配列(配列(12, 7)、配列(12, 26)、配列(39, 14)、配列(22) , 41)), //35
array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
array(array(17) , 4)、配列(29, 14)、配列(49, 10)、配列(24, 46))、
配列(配列( 4, 18)、配列(13, 32)、配列(48, 14) ), array(42, 32)),
array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
array(array (19, 6), array(18, 31), array(34, 34), array(20, 61)),//40
);
// キャッシュ可能!!!
パブリック静的関数 getEccSpec($version, $level, array &$spec){
if (count($spec) $spec = array(0,0,0,0) ,0);
}
$b1 = self::$eccTable[$version][$level][0];
$b2 = self::$eccTable[$version][$level][1];
$data = self::getDataLength($version, $level);
$ecc = self::getECCLength($version, $level);
if($b2 == 0) {
$spec[0] = $b1;
$spec[1] = (int)($data / $b1);
$spec[2] = (int)($ecc / $b1);
$spec[3] = 0;
$spec[4] = 0;
} else {
$spec[0] = $b1;
$spec[1] = (int)($data / ($b1 $b2));
$spec[2] = (int)($ecc / ($b1 $b2));
$spec[3] = $b2;
$spec[4] = $spec[1] 1;
}
}
public static $alignmentPattern = array(
array( 0, 0),
array( 0, 0), array(18, 0), array(22, 0) ), array(26, 0), array(30, 0), // 1-5
array(34, 0), array(22, 38), array(24, 42), array(26, 46) ), array(28, 50), // 6-10
array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48) ), //11-15
配列(26, 50), 配列(30, 54), 配列(30, 56), 配列(30, 58), 配列(34, 62), //16-20
array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
array(24, 50), array(28, 54), array(32, 58)、配列(26, 54)、配列(30, 58)、//35-40
);
public static function putAlignmentMarker(array &$frame, $ox, $oy){
$finder = array(
"xa1xa1xa1xa1xa1",
"xa1xa0xa0xa0xa1",
"xa1xa0xa1xa0xa1",
"xa1xa0xa0xa0xa1",
"xa1xa1xa1xa1xa1"
);
$yStart = $oy-2;
$xStart = $ox-2;
for($y=0; $yQRstr::set($frame, $xStart, $yStart $y, $finder[$y]);
}
}
パブリック静的関数 putAlignmentPattern($version, &$frame, $width){
if($version return;
$d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
if($d $w = 2;
}else {
$w = (int)(($width - self::$alignmentPattern[$version][0]) / $d 2);
}
if($w * $w - 3 == 1) {
$x = self::$alignmentPattern[$version][0];
$y = self::$alignmentPattern[$version][0];
self::putAlignmentMarker($frame, $x, $y);
戻る;
}
$cx = self::$alignmentPattern[$version][0];
for($x=1; $xself::putAlignmentMarker($frame, 6, $cx);
self::putAlignmentMarker($frame, $cx, 6);
$cx = $d;
}
$cy = self::$alignmentPattern[$version][0];
for($y=0; $y$cx = self::$alignmentPattern[$version][0];
for($x=0; $xself::putAlignmentMarker($frame, $cx, $cy);
$cx = $d;
}
$cy = $d;
}
}
public static $versionPattern = array(
0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
0x0f928, 10b78、0x1145d、0x12a17、0x13532、 0x149a6、0x15683、0x168c9、
0x177ec、0x18ec4、0x191e1、0x1afab、0x1b08e、0x1cc1a、0x1d33f、0x1ed75、
0x1f250、0x209d5、0 x216f0、0x228ba、0x2379f、0x24b0b、0x2542e、0x26a64、
0x27541、0x28c69
);
public static function getVersionPattern($version){
if($version QRSPEC_VERSION_MAX)
return 0;
return self::$versionPattern[$version -7];
}
// フォーマット情報 -------------------------------------- -----------
// testing/test_qrspec.c の calcFormatInfo を参照 (オリジナルの qrencode C lib)
public static $formatInfo = array(
array(0x77c4, 0x72f3, 0x7daa) 、0x789d、0x662f、0x6318、0x6c41、0x6976)、
配列(0x5412、0x5125、0x5e7c、0x5b4b、0x45f9、0x40ce、0x4f97、0x4aa0)、 0x355f、0x3068、0x3f31、0x3a06、0x24b4、0x2183 、0x2eda、0x2bed)、
array(0x1689、0x13be、0x1ce7、0x19d0、0x0762、0x0255、0x0d0c、0x083b)
);
public static function getFormatInfo($mask, $level){
if($mask 7)
return 0;
if($level 3)
return 0;
return self::$formatInfo[$level][$mask];
}
// フレーム -------------------------------------- -----------------------
// 初期フレームのキャッシュ。
パブリック静的 $frames = array();
public static function putFinderPattern(&$frame, $ox, $oy){
$finder = array(
"xc1xc1xc1xc1xc1xc1xc1",
"xc1xc0xc0xc0xc0xc0xc1",
"xc1xc0xc1xc1xc1 xc0xc1"、
"xc1xc0xc1xc1xc1xc0xc1"、
"xc1xc0xc1xc1xc1xc0xc1"、
"xc1xc0xc0xc0xc0xc0xc1"、
"xc1xc1xc1xc1xc1xc1xc1"
);
for($y=0; $yQRstr::set($frame, $ox, $oy $y, $finder[$y]);
}
}
public static function createFrame($version){
$width = self::$capacity[$version][QRCAP_WIDTH];
$frameLine = str_repeat (" ", $width);
$frame = array_fill(0, $width, $frameLine);
// ファインダーパターン
self::putFinderPattern($frame, 0, 0);
self::putFinderPattern($frame, $width - 7, 0);
self::putFinderPattern($frame, 0, $width - 7);
// 区切り文字
$yOffset = $width - 7;
for($y=0; $y$frame[$y][7] = "xc0";
$frame[$y][$width - 8] = "xc0";
$frame[$yOffset][7] = "xc0";
$yOffset ;
}
$setPattern = str_repeat("xc0", 8);
QRstr::set($frame, 0, 7, $setPattern);
QRstr::set($frame, $width-8, 7, $setPattern);
QRstr::set($frame, 0, $width - 8, $setPattern);
// フォーマット情報
$setPattern = str_repeat("x84", 9);
QRstr::set($frame, 0, 8, $setPattern);
QRstr::set($frame, $width - 8, 8, $setPattern, 8);
$yOffset = $width - 8;
for($y=0; $y$frame[$y][8] = "x84";
$frame[$yOffset][8] = "x84";
}
// タイミング パターン
for($i=1; $i$frame[6][7 $i] = chr(0x90 | ($i & 1));
$frame[7 $i][6] = chr(0x90 | ($i & 1));
}
// 配置パターン
self::putAlignmentPattern($version, $frame, $width);
// バージョン情報
if($version >= 7) {
$vinf = self::getVersionPattern($version);
$v = $vinf;
for($x=0; $xfor($y=0; $y$frame[($width - 11) $y][$x] = chr(0x88 | ($v & 1));
$v = $v >> 1;
}
}
$v = $vinf;
for($y=0; $yfor($x=0; $x$frame[$y][$x ($width - 11)] = chr(0x88 | ($v & 1));
$v = $v >> 1;
}
}
}
// そして少し...
$frame[$width - 8][8] = "x81";
$frame を返します;
}
public static function debug($frame, $binary_mode = false){
if ($binary_mode) {
foreach ($frame as &$frameLine) {
$frameLine = join (' ',explode('0', $frameLine));
$frameLine = join('██',explode('1', $frameLine));
}

.m {背景色: 白; }

echo '
<tt><br>gt;<br>gt;<br>        '; <br>echo join("<br> ", $frame); <br>エコー '</tt>






} else {
foreach ($frame as &$frameLine) {
$frameLine = join(' ',explode("xc0" 、$frameLine));
$frameLine = join('',explode("xc1", $frameLine));
$frameLine = join(' ',explode("xa0", $frameLine));
$frameLine = join('',explode("xa1", $frameLine));
$frameLine = join('',explode("x84", $frameLine)); //フォーマット 0
$frameLine = join('',explode("x85", $frameLine)); //形式 1
$frameLine = join('',explode("x81", $frameLine)); //特別なビット
$frameLine = join(' ',explode("x90", $frameLine)); //クロック 0
$frameLine = join('',explode("x91", $frameLine)); //クロック 1
$frameLine = join(' ',explode("x88", $frameLine)); //バージョン
$frameLine = join('',explode("x89", $frameLine)); //バージョン
$frameLine = join('♦',explode("x01", $frameLine));
$frameLine = join('⋅',explode(" ", $frameLine));
}

.p {背景色: 黄色; }
.m {背景色: #00FF00; }
.s {背景色: #FF0000; }
.c {背景色: アクア; }
.x {背景色: ピンク; }
.f {背景色: ゴールド; }

echo "
<tt>"; <br>echo join("<br>", $frame); <br>エコー "</tt>
";
}
}
パブリック静的関数 Serial($frame){
return gzcompress(join("n", $frame), 9);
}
public static function unserial($code){
returnexplode("n", gzuncompress($code));
}
public static function newFrame($version){
if($version QRSPEC_VERSION_MAX)
return null;
if(!isset(self::$frames[$version])) {
$fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
if (QR_CACHEABLE) {
if (file_exists($fileName)) {
self::$frames[$version] = self::unserial(file_get_contents($fileName));
} else {
self::$frames[$version] = self::createFrame($version);
file_put_contents($fileName, self::serial(self::$frames[$version]));
}
} else {
self::$frames[$version] = self::createFrame($version);
}
}
if(is_null(self::$frames[$version]))
return null;
return self::$frames[$version];
}
パブリック静的関数 rsBlockNum($spec) { return $spec[0] $spec[3]; }
パブリック静的関数 rsBlockNum1($spec) { return $spec[0]; }
パブリック静的関数 rsDataCodes1($spec) { return $spec[1]; }
パブリック静的関数 rsEccCodes1($spec) { return $spec[2]; }
パブリック静的関数 rsBlockNum2($spec) { return $spec[3]; }
パブリック静的関数 rsDataCodes2($spec) { return $spec[4]; }
パブリック静的関数 rsEccCodes2($spec) { return $spec[2]; }
public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) ($spec[3] * $spec[4]); }
パブリック静的関数 rsEccLength($spec) { return ($spec[0] $spec[3]) * $spec[2];
}
define('QR_IMAGE', true);
class QRimage {
public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE){
$image = self::image($フレーム、$pixelPerPoint、$outerFrame);
if ($filename === false) {
Header("Content-type: image/png");
ImagePng($image);
} else {
if($saveandprint===TRUE){
ImagePng($image, $filename);
header("Content-type: image/png");
ImagePng($image);
}else{
ImagePng($image, $filename);
}
}
ImageDestroy($image);
}
パブリック静的関数 jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85){
$image = self::image($frame, $pixelPerPoint、$outerFrame);
if ($filename === false) {
Header("Content-type: image/jpeg");
ImageJpeg($image, null, $q);
} else {
ImageJpeg($image, $filename, $q);
}
ImageDestroy($image);
}
プライベート静的関数 image($frame, $pixelPerPoint = 4, $outerFrame = 4){
$h = count($frame);
$w = strlen($frame[0]);
$imgW = $w 2*$outerFrame;
$imgH = $h 2*$outerFrame;
$base_image =ImageCreate($imgW, $imgH);
$col[0] = ImageColorAllocate($base_image,255,255,255);
$col[1] = ImageColorAllocate($base_image,0,0,0);
imagefill($base_image, 0, 0, $col[0]);
for($y=0; $yfor($x=0; $xif ($frame[$y ][$x] == '1') {
ImageSetPixel($base_image,$x $outerFrame,$y $outerFrame,$col[1]);
}
}
}
$target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
ImageCopyResize($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
ImageDestroy($base_image);
$target_image を返す;
}
}
define('STRUCTURE_HEADER_BITS', 20);
define('MAX_STRUCTURED_SYMBOLS', 16);
class QRinputItem {
public $mode;
パブリック $size;
パブリック $data;
パブリック $bstream;
パブリック関数 __construct($mode, $size, $data, $bstream = null){
$setData = array_slice($data, 0, $size);
if (count($setData) $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
}
if(!QRinput::check($mode, $size, $setData)) {
throw new Exception('Error m:'.$mode.',s:'.$size .',d:'.join(',',$setData));
null を返します。
}
$this->mode = $mode;
$this->size = $size;
$this->data = $setData;
$this->bstream = $bstream;
}
public function encodeModeNum($version){
try {
$words = (int)($this->size / 3);
$bs = 新しい QRbitstream();
$val = 0x1;
$bs->appendNum(4, $val);
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
for($i=0; $i$val = (ord($this->data[$i*3 ]) - ord('0')) * 100;
$val = (ord($this->data[$i*3 1]) - ord('0')) * 10;
$val = (ord($this->data[$i*3 2]) - ord('0'));
$bs->appendNum(10, $val);
}
if($this->size - $words * 3 == 1) {
$val = ord($this->data[$words*3]) - ord(' 0');
$bs->appendNum(4, $val);
} else if($this->size - $words * 3 == 2) {
$val = (ord($this->data[$words*3 ]) - ord('0 ')) * 10;
$val = (ord($this->data[$words*3 1]) - ord('0'));
$bs->appendNum(7, $val);
}
$this->bstream = $bs;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
public function encodeModeAn($version){
try {
$words = (int)($this->size / 2);
$bs = 新しい QRbitstream();
$bs->appendNum(4, 0x02);
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
for($i=0; $i$val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45;
$val = (int)QRinput::lookAnTable(ord($this->data[$i*2 1]));
$bs->appendNum(11, $val);
}
if($this->size & 1) {
$val = QRinput::lookAnTable(ord($this->data[$words * 2]));
$bs->appendNum(6, $val);
}
$this->bstream = $bs;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
public function encodeMode8($version){
try {
$bs = new QRbitstream();
$bs->appendNum(4, 0x4);
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
for($i=0; $isize; $i ) {
$bs->appendNum(8, ord($this->data[$i])) ;
}
$this->bstream = $bs;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
public function encodeModeKanji($version){
try {
$bs = new QRbitrtream();
$bs->appendNum(4, 0x8);
$bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));
for($i=0; $isize; $i =2) {
$val = (ord($this->data[$i]) data[$i 1]);
if($val $val -= 0x8140;
} else {
$val -= 0xc140;
}
$h = ($val >> 8) * 0xc0;
$val = ($val & 0xff) $h;
$bs->appendNum(13, $val);
}
$this->bstream = $bs;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
public function encodeModeStructure(){
try {
$bs = new QRbitstream();
$bs->appendNum(4, 0x03);
$bs->appendNum(4, ord($this->data[1]) - 1);
$bs->appendNum(4, ord($this->data[0]) - 1);
$bs->appendNum(8, ord($this->data[2]));
$this->bstream = $bs;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
パブリック関数estimateBitStreamSizeOfEntry($version){
$bits = 0;
if($version == 0)
$version = 1;
switch($this->mode) {
case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size);壊す;
case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size);壊す;
case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size);壊す;
case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break;
QR_MODE_STRUCTURE の場合: STRUCTURE_HEADER_BITS を返します。
デフォルト:
0 を返します。
}
$l = QRspec::lengthIndicator($this->mode, $version);
$m = 1 $num = (int)(($this->size $m - 1) / $m);
$bits = $num * (4 $l);
$bits を返します;
}
public function encodeBitStream($version){
try {
unset($this->bstream);
$words = QRspec::maximumWords($this->mode, $version);
if($this->size > $words) {
$st1 = new QRinputItem($this->mode, $words, $this->data);
$st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
$st1->encodeBitStream($version);
$st2->encodeBitStream($version);
$this->bstream = new QRbitstream();
$this->bstream->append($st1->bstream);
$this->bstream->append($st2->bstream);
設定を解除($st1);
設定を解除($st2);
} else {
$ret = 0;
switch($this->mode) {
case QR_MODE_NUM: $ret = $this->encodeModeNum($version);壊す;
case QR_MODE_AN: $ret = $this->encodeModeAn($version);壊す;
case QR_MODE_8: $ret = $this->encodeMode8($version);壊す;
case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break;
case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure();壊す;
デフォルト:
ブレーク;
}
if($ret return -1;
}
return $this->bstream->size();
} catch (Exception $e) {
return -1;
}
}
};
class QRinput {
public $items;
プライベート $バージョン;
プライベート $レベル;
public function __construct($version = 0, $level = QR_ECLEVEL_L){
if ($version QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
新しい例外をスローする('無効なバージョン番号');
NULL を返します。
}
$this->version = $version;
$this->level = $level;
}
public function getVersion(){
return $this->version;
}
public function setVersion($version){
if($version QRSPEC_VERSION_MAX) {
throw new Exception('無効なバージョン番号');
-1 を返す;
}
$this->version = $version;
0 を返す;
}
public function getErrorCorrectionLevel(){
return $this->level;
}
public function setErrorCorrectionLevel($level){
if($level > QR_ECLEVEL_H) {
throw new Exception('Invalid ECLEVEL');
-1 を返す;
}
$this->level = $level;
0 を返す;
}
public function appendEntry(QRinputItem $entry){
$this->items[] = $entry;
}
public function append($mode, $size, $data){
try {
$entry = new QRinputItem($mode, $size, $data);
$this->items[] = $entry;
0 を返す;
} catch (Exception $e) {
return -1;
}
}
public function insertStructuredAppendHeader($size, $index, $parity){
if( $size > MAX_STRUCTURED_SYMBOLS ) {
throw new Exception('insertStructuredAppendHeader のサイズが間違っています') ;
}
if( $index MAX_STRUCTURED_SYMBOLS ) {
throw new Exception('insertStructuredAppendHeader 間違ったインデックス');
}
$buf = array($size, $index, $parity);
try {
$entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
array_unshift($this->items, $entry);
0 を返す;
} catch (Exception $e) {
return -1;
}
}
パブリック関数 calcParity(){
$parity = 0;
foreach($this->items as $item) {
if($item->mode != QR_MODE_STRUCTURE) {
for($i=$item->size-1; $ i>=0; $i--) {
$parity ^= $item->data[$i];
}
}
}
return $parity;
}
パブリック静的関数 checkModeNum($size, $data){
for($i=0; $iif((ord($data[ $i]) ord('9')){
return false;
}
}
true を返します。
}
パブリック静的関数estimateBitsModeNum($size){
$w = (int)$size / 3;
$bits = $w * 10;
switch($size - $w * 3) {
ケース 1:
$bits = 4;
休憩;
ケース 2:
$bits = 7;
休憩;
デフォルト:
ブレーク;
}
$bits を返します。
}
public static $anTable = array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 1、-1、-1、-1、
-1、-1、-1、-1、-1、-1、-1、-1、-1、-1、-1、-1、 -1、-1、-1、-1、
36、-1、-1、-1、37、38、-1、-1、-1、-1、39、40、-1、41 、42、43、
0、1、2、3、4、5、6、7、8、9、44、-1、-1、-1、-1、-1、
-1 、10、11、12、13、14、15、16、17、18、19、20、21、22、23、24、
25、26、27、28、29、30、31、32、 33、34、35、-1、-1、-1、-1、-1、
-1、-1、-1、-1、-1、-1、-1、-1、-1 、-1、-1、-1、-1、-1、-1、-1、
-1、-1、-1、-1、-1、-1、-1、-1、- 1、-1、-1、-1、-1、-1、-1、-1
);
public static function lookAnTable($c){
return (($c > 127)?-1:self::$anTable[$c]);
}
public static function checkModeAn($size, $data){
for($i=0; $iif (self::lookAnTable(ord) ($data[$i])) == -1) {
return false;
}
}
true を返します。
}
パブリック静的関数estimateBitsModeAn($size){
$w = (int)($size / 2);
$bits = $w * 11;
if($size & 1) {
$bits = 6;
}
$bits を返します。
}
パブリック静的関数estimateBitsMode8($size){
return $size * 8;
}
パブリック関数estimateBitsModeKanji($size){
return (int)(($size / 2) * 13);
}
パブリック静的関数 checkModeKanji($size, $data){
if($size & 1)
return false;
for($i=0; $i$val = (ord($data[$i]) if( $val || ($val > 0x9ffc && $val || $val > 0xebbf) {
return false;
}
}
true を返します。
}
public static function check($mode, $size, $data){
if($size return false;
switch($mode) {
case QR_MODE_NUM: return self::checkModeNum($size, $data);壊す;
case QR_MODE_AN: return self::checkModeAn($size, $data);壊す;
case QR_MODE_KANJI: return self::checkModeKanji($size, $data);壊す;
QR_MODE_8 の場合: true を返します。壊す;
QR_MODE_STRUCTURE の場合: true を返します。壊す;
デフォルト:
ブレーク;
}
false を返します。
}
パブリック関数estimateBitStreamSize($version){
$bits = 0;
foreach($this->items as $item) {
$bits = $item->estimateBitStreamSizeOfEntry($version);
}
$bits を返します。
}
パブリック関数estimateVersion(){
$version = 0;
$prev = 0;
do {
$prev = $version;
$bits = $this->estimateBitStreamSize($prev);
$version = QRspec::getMinimumVersion((int)(($bits 7) / 8), $this->level);
if ($version return -1;
}
} while ($version > $prev);
$version を返します;
}
public static function lengthOfCode($mode, $version, $bits){
$payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
switch($mode) {
case QR_MODE_NUM:
$chunks = (int)($payload / 10);
$remain = $payload - $chunks * 10;
$size = $chunks * 3;
if($remain >= 7) {
$size = 2;
} else if($remain >= 4) {
$size = 1;
}
休憩;
ケース QR_MODE_AN:
$chunks = (int)($payload / 11);
$remain = $payload - $chunks * 11;
$size = $chunks * 2;
if($remain >= 6)
$size ;
休憩;
ケース QR_MODE_8:
$size = (int)($payload / 8);
休憩;
case QR_MODE_KANJI:
$size = (int)(($payload / 13) * 2);
休憩;
ケース QR_MODE_STRUCTURE:
$size = (int)($payload / 8);
休憩;
デフォルト:
$size = 0;
休憩;
}
$maxsize = QRspec::maximumWords($mode, $version);
if($size if($size > $maxsize) $size = $maxsize;
$size を返します;
}
パブリック関数 createBitStream(){
$total = 0;
foreach($this->items as $item) {
$bits = $item->encodeBitStream($this->version);
if($bits return -1;
$total = $bits;
}
$total を返す;
}
パブリック関数 ConvertData(){
$ver = $this->estimateVersion();
if($ver > $this->getVersion()) {
$this->setVersion($ver);
}
for(;;) {
$bits = $this->createBitStream();
if($bits return -1;
$ver = QRspec::getMinimumVersion((int)(($bits 7) / 8), $this->level);
if($ver throw new Exception('WRONG VERSION');
-1 を返す;
} else if($ver > $this->getVersion()) {
$this->setVersion($ver);
} else {
ブレーク;
}
}
0 を返す;
}
public function appendPaddingBit(&$bstream){
$bits = $bstream->size();
$maxwords = QRspec::getDataLength($this->version, $this->level);
$maxbits = $maxwords * 8;
if ($maxbits == $bits) {
return 0;
}
if ($maxbits - $bits return $bstream->appendNum($maxbits - $bits, 0);
}
$ビット = 4;
$words = (int)(($bits 7) / 8);
$padding = 新しい QRbitstream();
$ret = $padding->appendNum($words * 8 - $bits 4, 0);
if($ret return $ret;
$padlen = $maxwords - $words;
if($padlen > 0) {
$padbuf = array();
for($i=0; $i$padbuf[$i] = ($i&1)?0x11:0xec;
}
$ret = $padding->appendBytes($padlen, $padbuf);
if($ret return $ret;
}
$ret = $bstream->append($padding);
$ret を返す;
}
public function mergeBitStream(){
if($this->convertData() return null;
}
$bstream = 新しい QRbitstream();
foreach($this->items as $item) {
$ret = $bstream->append($item->bstream);
if($ret null を返す;
}
}
return $bstream;
}
パブリック関数 getBitStream(){
$bstream = $this->mergeBitStream();
if($bstream == null) {
return null;
}
$ret = $this->appendPaddingBit($bstream);
if($ret null を返す;
}
return $bstream;
}
パブリック関数 getByteStream(){
$bstream = $this->getBitStream();
if($bstream == null) {
return null;
}
return $bstream->toByte();
}
}
class QRbitstream {
public $data = array();
パブリック関数 size(){
return count($this->data);
}
public function assign($setLength){
$this->data = array_fill(0, $setLength, 0);
0 を返す;
}
パブリック静的関数 newFromNum($bits, $num){
$bstream = new QRbitstream();
$bstream->allocate($bits);
$マスク = 1 for($i=0; $iif($num & $mask) {
$bstream->data[$i] = 1;
} else {
$bstream->data[$i] = 0;
}
$mask = $mask >> 1;
}
return $bstream;
}
パブリック静的関数 newFromBytes($size, $data){
$bstream = new QRbitstream();
$bstream->allocate($size * 8);
$p=0;
for($i=0; $i$mask = 0x80;
for($j=0; $jif($data[$i] & $mask) {
$bstream->data[$p] = 1 ;
} else {
$bstream->data[$p] = 0;
}
$p ;
$マスク = $マスク>> 1;
}
}
return $bstream;
}
public function append(QRbitstream $arg){
if (is_null($arg)) {
return -1;
}
if($arg->size() == 0) {
return 0;
}
if($this->size() == 0) {
$this->data = $arg->data;
0 を返す;
}
$this->data = array_values(array_merge($this->data, $arg->data));
0 を返す;
}
public function appendNum($bits, $num){
if ($bits == 0)
return 0;
$b = QRbitstream::newFromNum($bits, $num);
if(is_null($b))
return -1;
$ret = $this->append($b);
設定を解除($b);
$ret を返す;
}
public function appendBytes($size, $data){
if ($size == 0)
return 0;
$b = QRbitstream::newFromBytes($size, $data);
if(is_null($b))
return -1;
$ret = $this->append($b);
設定を解除($b);
$ret を返す;
}
パブリック関数 toByte(){
$size = $this->size();
if($size == 0) {
return array();
}
$data = array_fill(0, (int)(($size 7) / 8), 0);
$bytes = (int)($size / 8);
$p = 0;
for($i=0; $i$v = 0;
for($j=0; $j$v = $v $v |= $this->data[$p];
$p ;
}
$data[$i] = $v;
}
if($size & 7) {
$v = 0;
for($j=0; $j$v = $v $v |= $this->data[$p];
$p ;
}
$data[$bytes] = $v;
}
$data を返します。
}
}
class QRsplit {
public $dataStr = '';
パブリック $input;
パブリック $modeHint;
パブリック関数 __construct($dataStr, $input, $modeHint){
$this->dataStr = $dataStr;
$this->input = $input;
$this->modeHint = $modeHint;
}
public static function isdigitalat($str, $pos){
if ($pos >= strlen($str))
return false;
return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) }
public static function isalnumat($str, $pos){
if ($pos >= strlen($str))
return false;
return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
}
public functionidentifyMode($pos){
if ($pos >= strlen($this->dataStr))
return QR_MODE_NUL;
$c = $this->dataStr[$pos];
if(self::isdigitalat($this->dataStr, $pos)) {
return QR_MODE_NUM;
} else if(self::isalnutat($this->dataStr, $pos)) {
return QR_MODE_AN;
}else if($this->modeHint == QR_MODE_KANJI) {
if ($pos 1 dataStr))
{
$d = $this->dataStr [$pos 1];
$word = (ord($c) if(($word >= 0x8140 && $word = 0xe040 && $word return QR_MODE_KANJI;
}
}
}
QR_MODE_8 を返す;
}
public function EatNum(){
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
$p = 0;
while(self::isdigitalat($this->dataStr, $p)) {
$p ;
}
$run = $p;
$mode = $this->identifyMode($p);
if($mode == QR_MODE_8) {
$dif = QRinput::estimateBitsModeNum($run) 4 $ln
QRinput::estimateBitsMode8(1) // 4 l8
- QRinput:: estimateBitsMode8($run 1); // - 4 - l8
if($dif > 0) {
return $this->eat8();
}
}
if($mode == QR_MODE_AN) {
$dif = QRinput::estimateBitsModeNum($run) 4 $ln
QRinput::estimateBitsModeAn(1) // 4 la
- QRinput::estimateBitsModeAn($run 1);// - 4 - la
if($dif > 0) {
return $this->eatAn();
}
}
$ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
if($ret return -1;
$run を返す;
}
public function EatAn(){
$la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
$p = 0;
while(self::isalumat($this->dataStr, $p)) {
if(self::isdigitalat($this->dataStr, $p)) {
$q = $p;
while(self::isdigitalat($this->dataStr, $q)) {
$q ;
}
$dif = QRinput::estimateBitsModeAn($p) // 4 la
QRinput::estimateBitsModeNum($q - $p) 4 $ln
- QRinput::estimateBitsModeAn($q) ); // - 4 - la
if($dif break;
} else {
$p = $q;
}
} else {
$p ;
}
}
$run = $p;
if(!self::isalnutat($this->dataStr, $p)) {
$dif = QRinput::estimateBitsModeAn($run) 4 $la
QRinput::estimateBitsMode8(1) // 4 l8
- QRinput::estimateBitsMode8($run 1); // - 4 - l8
if($dif > 0) {
return $this->eat8();
}
}
$ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
if($ret return -1;
$run を返す;
}
パブリック関数 EatKanji(){
$p = 0;
while($this->identifyMode($p) == QR_MODE_KANJI) {
$p = 2;
}
$ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
if($ret return -1;
$run を返す;
}
public function Eat8(){
$la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
$ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
$p = 1;
$dataStrLen = strlen($this->dataStr);
while($p $mode = $this->identifyMode($p);
if($mode == QR_MODE_KANJI) {
ブレーク;
}
if($mode == QR_MODE_NUM) {
$q = $p;
while(self::isdigitalat($this->dataStr, $q)) {
$q ;
}
$dif = QRinput::estimateBitsMode8($p) // 4 l8
QRinput::estimateBitsModeNum($q - $p) 4 $ln
- QRinput::estimateBitsMode8($q) ); // - 4 - l8
if($dif break;
} else {
$p = $q;
}
} else if($mode == QR_MODE_AN) {
$q = $p;
while(self::isalnutat($this->dataStr, $q)) {
$q ;
}
$dif = QRinput::estimateBitsMode8($p) // 4 l8
QRinput::estimateBitsModeAn($q - $p) 4 $la
- QRinput::estimateBitsMode8($q) ); // - 4 - l8
if($dif break;
} else {
$p = $q;
}
} else {
$p ;
}
}
$run = $p;
$ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
if($ret return -1;
$run を返す;
}
public function splitString(){
while (strlen($this->dataStr) > 0)
{
if($this->dataStr == '' )
0 を返す;
$mode = $this->identifyMode(0);
switch ($mode) {
case QR_MODE_NUM: $length = $this->eatNum();壊す;
ケース QR_MODE_AN: $length = $this->eatAn();壊す;
case QR_MODE_KANJI:
if ($hint == QR_MODE_KANJI)
$length = $this->eatKanji();
else $length = $this->eat8();
休憩;
デフォルト: $length = $this->eat8();壊す;
}
if($length == 0) 0 を返します。
if($length $this->dataStr = substr($this->dataStr, $length);
}
}
パブリック関数 toUpper(){
$stringLen = strlen($this->dataStr);
$p = 0;
while ($p$mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);
if($mode == QR_MODE_KANJI) {
$p = 2;
} else {
if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
}
$p ;
}
}
return $this->dataStr;
}
public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true){
if(is_null($string) || $string == ' ' || $string == '') {
新しい例外をスローします('空の文字列!!!');
}
$split = new QRsplit($string, $input, $modeHint);
if(!$casesensitive)
$split->toUpper();
return $split->splitString();
}
}
class QRrsItem {
public $mm; // シンボルあたりのビット数
public $nn; // ブロックごとのシンボル数 (= (1public $alpha_to = array(); // ログ検索テーブル
public $index_of = array(); // 逆対数ルックアップ テーブル
public $genpoly = array(); // 生成多項式
public $nroots; // ジェネレーターのルートの数 = パリティ シンボルの数
public $fcr; // 最初の連続したルート、インデックス形式
public $prim; // プリミティブ要素、インデックス形式
public $iprim; // 1 の主根、インデックス形式
public $pad; // 短縮されたブロックにバイトを埋め込みます
public $gfpoly;
public function modnn($x){
while ($x >= $this->nn) {
$x -= $this->nn;
$x = ($x >> $this->mm) ($x & $this->nn);
}
$x を返す;
}
public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad){
// リードソロモン制御ブロックを初期化するための共通コード (char または int)記号)
// Copyright 2004 Phil Karn, KA9Q
// GNU Lesser General Public License (LGPL) の条件に基づいて使用できます
$rs = null;
// パラメータの範囲を確認します
if($symssize 8) return $rs;
if($fcr = (1if($prim = (1if($nroots = (1if($pad = ((1$rs = new QRrsItem();
$rs->mm = $shmsize;
$rs->nn = (1$rs->pad = $pad;
$rs->alpha_to = array_fill(0, $rs->nn 1, 0);
$rs->index_of = array_fill(0, $rs->nn 1, 0);
// PHP スタイルのマクロ置換 ;)
$NN =& $rs->nn;
$A0 =& $NN;
// ガロア体ルックアップ テーブルを生成します
$rs->index_of[0] = $A0; // log(zero) = -inf
$rs->alpha_to[$A0] = 0; // alpha**-inf = 0
$sr = 1;
for($i=0; $inn; $i ) {
$rs->index_of[$sr] = $i;
$rs->alpha_to[$i] = $sr;
$sr if($sr & (1$sr ^= $gfpoly;
}
$sr &= $rs->nn;
}
if($sr != 1){
// 場生成多項式は原始的ではありません!
$rs = NULL;
$rs を返します;
}
/* RS コード生成多項式を根から作成します */
$rs->genpoly = array_fill(0, $nroots 1, 0);
$rs->fcr = $fcr;
$rs->prim = $prim;
$rs->nroots = $nroots;
$rs->gfpoly = $gfpoly;
/* デコードに使用される 1 の主根を検索します */
for($iprim=1;($iprim % $prim) != 0;$iprim = $rs->nn)
; // 意図的な空のループ!
$rs->iprim = (int)($iprim / $prim);
$rs->genpoly[0] = 1;
for ($i = 0,$root=$fcr*$prim; $i $rs->genpoly[$i 1] = 1;
// rs->genpoly[] に @**(root x) を掛けます
for ($j = $i; $j > 0; $j--) {
if ($ rs->genpoly[$j] != 0) {
$rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs ->modnn($rs->index_of[$rs->genpoly[$j]] $root)];
} else {
$rs->genpoly[$j] = $rs->genpoly[$j-1];
}
}
// rs->genpoly[0] をゼロにすることはできません
$rs->genpoly[0] = $rs->gt;alpha_to[$rs->> modnn($rs->index_of[$rs->genpoly[0]] $root)];
}
// rs->genpoly[] をインデックス形式に変換してエンコードを高速化します
for ($i = 0; $i $rs- >genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
$rs を返します;
}
パブリック関数 encode_rs_char($data, &$parity){
$MM =& $this->mm;
$NN =& $this->nn;
$ALPHA_TO =& $this->alpha_to;
$INDEX_OF =& $this->index_of;
$GENPOLY =& $this->genpoly;
$NROOTS =& $this->nroots;
$FCR =& $this->fcr;
$PRIM =& $this->プリム;
$IPRIM =& $this->iprim;
$PAD =& $this->パッド;
$A0 =& $NN;
$parity = array_fill(0, $NROOTS, 0);
for($i=0; $i$フィードバック = $INDEX_OF[$data[$i] ^ $parity[0]] ;
if($フィードバック != $A0) {
// フィードバック項はゼロ以外です
// GENPOLY[NROOTS] が 1 の場合、常に
// でなければならないため、この行は不要ですinit_rs()
$フィードバック = $this->modnn($NN - $GENPOLY[$NROOTS] $フィードバック); によって構築された多項式の場合です。
for($j=1;$j$parity[$j] ^= $ALPHA_TO[$this->modnn($フィードバック $GENPOLY[$NROOTS-$ j])];
}
}
// シフト
array_shift($parity);
if($フィードバック != $A0) {
array_push($parity, $ALPHA_TO[$this->modnn($フィードバック $GENPOLY[0])]);
} else {
array_push($parity, 0);
}
}
}
}
class QRrs {
public static $items = array();
パブリック静的関数 init_rs($sonymize, $gfpoly, $fcr, $prim, $nroots, $pad){
foreach(self::$items as $rs) {
if($rs- >pad != $pad) 続行;
if($rs->nroots != $nroots) 続行;
if($rs->mm != $shmsize) 続行;
if($rs->gfpoly != $gfpoly) 続行;
if($rs->fcr != $fcr) 続行;
if($rs->prim != $prim) 続行;
$rs を返します;
}
$rs = QRrsItem::init_rs_char($shmsize, $gfpoly, $fcr, $prim, $nroots, $pad);
array_unshift(self::$items, $rs);
$rs を返します;
}
}
define('N1', 3);
define('N2', 3);
define('N3', 40);
define('N4', 10);
class QRmask {
public $runLength = array();
//------------------------------------------ -------------------------
public function __construct(){
$this->runLength = array_fill(0, QRSPEC_WIDTH_MAX 1) 、0);
}
public function writeFormatInformation($width, &$frame, $mask, $level){
$blacks = 0;
$format = QRspec::getFormatInfo($mask, $level);
for($i=0; $iif($format & 1) {
$blacks = 2;
$v = 0x85;
} else {
$v = 0x84;
}
$frame[8][$width - 1 - $i] = chr($v);
if($i $frame[$i][8] = chr($v);
} else {
$frame[$i 1][8] = chr($v);
}
$format = $format >> 1;
}
for($i=0; $iif($format & 1) {
$blacks = 2;
$v = 0x85;
} else {
$v = 0x84;
}
$frame[$width - 7 $i][8] = chr($v);
if($i == 0) {
$frame[8][7] = chr($v);
} else {
$frame[8][6 - $i] = chr($v);
}
$format = $format >> 1;
}
$blacks を返します。
}
パブリック関数マスク0($x, $y) { return ($x $y)&1;
パブリック関数マスク1($x, $y) { return ($y&1); }
パブリック関数マスク 2($x, $y) { return ($x%3); }
パブリック関数マスク3($x, $y) { return ($x $y)%3;
パブリック関数マスク4($x, $y) { return (((int)($y/2)) ((int)($x/3)))&1;
パブリック関数マスク5($x, $y) { return (($x*$y)&1) ($x*$y)%3;
パブリック関数マスク6($x, $y) { return ((($x*$y)&1) ($x*$y)%3)&1;
パブリック関数マスク7($x, $y) { return ((($x*$y)%3) (($x $y)&1))&1; }
プライベート関数generateMaskNo($maskNo, $width, $frame){
$bitMask = array_fill(0, $width, array_fill(0, $width, 0));
for($y=0; $yfor($x=0; $xif(ord($frame[ $y][$x]) & 0x80) {
$bitMask[$y][$x] = 0;
} else {
$maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
$bitMask[$y][$x] = ($maskFunc == 0)?1:0;
}
}
}
return $bitMask;
}
パブリック静的関数 Serial($bitFrame){
$codeArr = array();
foreach ($bitFrame as $line)
$codeArr[] = join('', $line);
return gzcompress(join("n", $codeArr), 9);
}
パブリック静的関数 unserial($code){
$codeArr = array();
$codeLines =explode("n", gzuncompress($code));
foreach ($codeLines as $line)
$codeArr[] = str_split($line);
$codeArr を返す;
}
パブリック関数 makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false){
$b = 0;
$bitMask = array();
$fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
if (QR_CACHEABLE) {
if (file_exists($fileName)) {
$bitMask = self::unserial(file_get_contents($fileName));
} else {
$bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))
mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
file_put_contents($fileName, self::serial($bitMask));
}
} else {
$bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
}
if ($maskGenOnly)
return;
$d = $s;
for($y=0; $yfor($x=0; $xif($bitMask[$y ][$x] == 1) {
$d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][ $x]);
}
$b = (int)(ord($d[$y][$x]) & 1);
}
}
$b を返す;
}
public function makeMask($width, $frame, $maskNo, $level){
$masked = array_fill(0, $width, str_repeat(" ", $width));
$this->makeMaskNo($maskNo, $width, $frame, $masked);
$this->writeFormatInformation($width, $masked, $maskNo, $level);
$masked を返します;
}
パブリック関数 calcN1N3($length){
$デメリット = 0;
for($i=0; $iif($this->runLength[$i] >= 5) {
$デメリット = (N1 ( $this->runLength[$i] - 5));
}
if($i & 1) {
if(($i >= 3) && ($i runLength[ $i] % 3 == 0)) {
$fact = (int)($this->runLength[$i] / 3);
if(($this->runLength[$i-2] == $fact) &&
($this->runLength[$i-1] == $fact) &&
( $this->runLength[$i 1] == $fact) &&
($this->runLength[$i 2] == $fact)) {
if(($this->gt; runLength[$i-3] runLength[$i-3] >= (4 * $fact)) {
$デメリット = N3;
} else if((($i 3) >= $length) || ($this->runLength[$i 3] >= (4 * $fact))) {
$デメリット= N3;
}
}
}
}
}
リターン$デメリット;
}
パブリック関数 EvaluateSymbol($width, $frame){
$head = 0;
$デメリット = 0;
for($y=0; $y$head = 0;
$this->runLength[0] = 1;
$frameY = $frame[$y];
if ($y>0)
$frameYM = $frame[$y-1];
for($x=0; $xif(($x > 0) && ($y > 0)) {
$b22 = ord( $frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
$w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
if(($b22 | ($w22 ^ 1))&1) {
$デメリット = N2;
}
}
if(($x == 0) && (ord($frameY[$x]) & 1)) {
$this->runLength[0] = - 1;
$head = 1;
$this->runLength[$head] = 1;
} else if($x > 0) {
if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
$頭 ;
$this->runLength[$head] = 1;
} else {
$this->runLength[$head] ;
}
}
}
$デメリット = $this->calcN1N3($head 1);
}
for($x=0; $x$head = 0;
$this->runLength[0] = 1;
for($y=0; $yif($y == 0 && (ord($frame[$y][$x]) & 1)) {
$this->runLength[0] = -1;
$head = 1;
$this->runLength[$head] = 1;
} else if($y > 0) {
if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
$head ;
$this->runLength[$head] = 1;
} else {
$this->runLength[$head] ;
}
}
}
$デメリット = $this->calcN1N3($head 1);
}
$デメリットを返します;
}
パブリック関数マスク($width, $frame, $level){
$minDemerit = PHP_INT_MAX;
$bestMaskNum = 0;
$bestMask = array();
$checked_masks = array(0,1,2,3,4,5,6,7);
if (QR_FIND_FROM_RANDOM !== false) {
$howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);
for ($i = 0; $i $remPos = rand (0, count($checked_masks)-1);
unset($checked_masks[$remPos]);
$checked_masks = array_values($checked_masks);
}
}
$bestMask = $frame;
foreach($checked_masks as $i) {
$mask = array_fill(0, $width, str_repeat(" ", $width));
$デメリット = 0;
$blacks = 0;
$blacks = $this->makeMaskNo($i, $width, $frame, $mask);
$blacks = $this->writeFormatInformation($width, $mask, $i, $level);
$blacks = (int)(100 * $blacks / ($width * $width));
$デメリット = (int)((int)(abs($blacks - 50) / 5) * N4);
$demerit = $this->evaluateSymbol($width, $mask);
if($demerit $minDemerit = $minDemerit;
$bestMask = $mask;
$bestMaskNum = $i;
}
}
$bestMask を返す;
}
}
class QRrsblock {
public $dataLength;
パブリック $data = array();
パブリック $eccLength;
パブリック $ecc = array();
パブリック関数 __construct($dl, $data, $el, &$ecc, QRrsItem $rs){
$rs->encode_rs_char($data, $ecc);
$this->dataLength = $dl;
$this->data = $data;
$this->eccLength = $el;
$this->ecc = $ecc;
}
};
//############################################# ###########################
class QRrawcode {
public $version;
パブリック $datacode = array();
パブリック $ecccode = array();
パブリック $ブロック;
パブリック $rsblocks = array(); //RSblock の
public $count;
パブリック $dataLength;
パブリック $eccLength;
パブリック $b1;
パブリック関数 __construct(QRinput $input){
$spec = array(0,0,0,0,0);
$this->datacode = $input->getByteStream();
if(is_null($this->datacode)) {
throw new Exception('null input string');
}
QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
$this->version = $input->getVersion();
$this->b1 = QRspec::rsBlockNum1($spec);
$this->dataLength = QRspec::rsDataLength($spec);
$this->eccLength = QRspec::rsEccLength($spec);
$this->ecccode = array_fill(0, $this->eccLength, 0);
$this->blocks = QRspec::rsBlockNum($spec);
$ret = $this->init($spec);
if($ret throw new Exception('ブロック割り当てエラー');
null を返します。
}
$this->count = 0;
}
public function init(array $spec){
$dl = QRspec::rsDataCodes1($spec);
$el = QRspec::rsEccCodes1($spec);
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
$blockNo = 0;
$dataPos = 0;
$eccPos = 0;
for($i=0; $i<:rsblocknum1>$ecc = array_slice($this->ecccode,$eccPos);
$this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
$this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
$dataPos = $dl;
$eccPos = $el;
$blockNo ;
}
if(QRspec::rsBlockNum2($spec) == 0)
return 0;
$dl = QRspec::rsDataCodes2($spec);
$el = QRspec::rsEccCodes2($spec);
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
if($rs == NULL) は -1 を返します。
for($i=0; $i<:rsblocknum2>$ecc = array_slice($this->ecccode,$eccPos);
$this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
$this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);
$dataPos = $dl;
$eccPos = $el;
$blockNo ;
}
0 を返す;
}
パブリック関数 getCode(){
$ret;
if($this->count dataLength) {
$row = $this->count % $this->blocks;
$col = $this->カウント / $this->ブロック;
if($col >= $this->rsblocks[0]->dataLength) {
$row = $this->b1;
}
$ret = $this->rsblocks[$row]->data[$col];
} else if($this->count gt;dataLength $this->eccLength) {
$row = ($this->count - $this->dataLength) % $this->ブロック;
$col = ($this->count - $this->dataLength) / $this->blocks;
$ret = $this->rsblocks[$row]->ecc[$col];
} else {
return 0;
}
$this->count ;
$ret を返す;
}
}
クラス QRcode {
public $version;
パブリック $width;
パブリック $data;
public function encodeMask(QRinput $input, $mask){
if($input->getVersion() getVersion() > QRSPEC_VERSION_MAX) {
throw new Exception('間違ったバージョン');
}
if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
throw new Exception('wrong level');
}
$raw = 新しい QRrawcode($input);
QRtools::markTime('after_raw');
$version = $raw->version;
$width = QRspec::getWidth($version);
$frame = QRspec::newFrame($version);
$filler = new FrameFiller($width, $frame);
if(is_null($filler)) {
NULL を返す;
}
// インターリーブされたデータと ecc コード
for($i=0; $idataLength $raw->eccLength; $i ) {
$code = $raw->getCode();
$ビット = 0x80;
for($j=0; $j$addr = $filler->next();
$filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
$bit = $bit >> 1;
}
}
QRtools::markTime('after_filler');
設定を解除($raw);
// 残りビット
$j = QRspec::getRemainder($version);
for($i=0; $i$addr = $filler->next();
$filler->setFrameAt($addr, 0x02);
}
$frame = $filler->frame;
unset($filler);
// マスキング
$maskObj = new QRmask();
if($mask if (QR_FIND_BEST_MASK) {
$masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
} else {
$masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
}
}else {
$masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
}
if($masked == NULL) {
return NULL;
}
QRtools::markTime('after_mask');
$this->version = $version;
$this->width = $width;
$this->data = $masked;
$this を返します;
}
public function encodeInput(QRinput $input){
return $this->encodeMask($input, -1);
}
public function encodeString8bit($string, $version, $level){
if(string == NULL) {
throw new Exception('empty string!');
NULL を返します。
}
$input = new QRinput($version, $level);
if($input == NULL) NULL を返します。
$ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
if($ret unset($input);
NULL を返します。
}
return $this->encodeInput($input);
}
public function encodeString($string, $version, $level, $hint, $casesensitive){
if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
throw new Exception('悪いヒント');
NULL を返します。
}
$input = new QRinput($version, $level);
if($
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么查找字符串是第几位php怎么查找字符串是第几位Apr 22, 2022 pm 06:48 PM

查找方法:1、用strpos(),语法“strpos("字符串值","查找子串")+1”;2、用stripos(),语法“strpos("字符串值","查找子串")+1”。因为字符串是从0开始计数的,因此两个函数获取的位置需要进行加1处理。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール