クラスコード:
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);画像の幅 (ピクセル単位)、GD と PHP がそのような大きな画像を処理できるように調整します。 $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(); (!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');
}
パブリック静的関数 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;
echo '
';
foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
if ($p > 0) {
echo '
} else {
$startTime = $thisTime;
}
$p++;
$lastTime = $thisTime;
}
エコー「 」
';
}
}
//########################################### ###############################
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
配列( 61, 404, 0, 配列( 80, 150, 224, 264)),
配列( 65, 466, 0, 配列( 96, 176, 260, 308)),
配列( 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) )、
配列( 89, 901, 3, 配列( 180, 338, 504, 588)),
配列( 93, 991, 3, 配列( 196, 364, 546, 650)),
配列( 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
array(141, 2323, 3, array( 480, 868, 1290) , 1530)),
array(145, 2465, 3, array( 510, 924, 1350, 1620)),
array(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];
}
パブリック静的関数 getWidth($version){
return self::$capacity[$version][QRCAP_WIDTH];
}
パブリック静的関数 getRemainder($version){
return self::$capacity[$version][QRCAP_REMINDER];
}
パブリック静的関数 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)、
配列(8, 16, 16)、
配列(8, 10, 12)
);
パブリック静的関数 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];
}
パブリック静的関数maximumWords($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)、配列( 2, 4)、配列( 4, 1))、
配列(配列( 2, 0)、配列( 2, 2)、配列( 4, 2)、配列( 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)、配列( 9, 4)、配列(17, 1)、配列( 2, 19))、
配列(配列( 3, 4)、配列( 3, 11)、配列(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))、
配列(配列( 4, 5), 配列( 4, 14), 配列(11, 14), 配列(16, 14)),
配列(配列( 6, 4) 、array( 6, 14)、array(11, 16)、array(30, 2))、
array(array( 8, 4)、array( 8, 13)、array( 7, 22)、array(22) , 13)), //25
array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
array(array( 3, 10), array( 3, 23), array( 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), array(42, 1), array(23, 28) ))、
配列(配列(17, 0), 配列(10, 23), 配列(10, 35), 配列(19, 35)),
配列(配列(17, 1), 配列(14, 21) )、配列(29, 19)、配列(11, 46))、
配列(配列(13, 6)、配列(14, 23)、配列(44, 7)、配列(59, 1))、
array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
array(array( 6, 14), array( 6, 34) 、配列(46, 10), 配列(2, 64)),
配列(配列(17, 4), 配列(29, 14), 配列(49, 10), 配列(24, 46)),
配列(配列( 4, 18), 配列(13, 32), 配列(48, 14), 配列(42, 32)),
配列(配列(20, 4), 配列(40, 7), 配列(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
配列(30, 54), 配列(32, 58), 配列(34, 62), 配列(26, 46), 配列(26, 48), //11-15
配列(26, 50) , array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
array(28, 50), array(26, 50), array (30, 54), 配列(28, 54), 配列(32, 58), //21-25
配列(30, 58), 配列(34, 62), 配列(26, 50), 配列(30) , 54), array(26, 52), //26-30
array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54) ), //31-35
配列(24, 50), 配列(28, 54), 配列(32, 58), 配列(26, 54), 配列(30, 58), //35-40
) ;
public static function putAlignmentMarker(array &$frame, $ox, $oy){
$finder = array(
"xa1xa1xa1xa1xa1",
"xa1xa0xa0xa0xa1",
"xa1xa0xa1xa0xa1", a0xa0xa1"、
"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, 、0x1145d、0x12a17、0x13532、0x149a6、0x15683、0x168c9、
0x177ec、0x18ec4 、0x191e1、0x1afab、0x1b08e、0x1cc1a、0x1d33f、0x1ed75、
0x1f250、0x209d5、0x216f0、0x228ba、0x2379f、0x24b0b、0x2542e、 a64、
0x27541、0x28c69
);
パブリック静的関数 getVersionPattern($version){
if($version QRSPEC_VERSION_MAX)
return 0;
return self::$versionPattern[$version -7];
}
// フォーマット情報 ---------------------------------------- -------
// testing/test_qrspec.c (オリジナルの qrencode C lib) の calcFormatInfo を参照
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、 2183, 0x2eda, 0x2bed),
array(0x1689, 0x13be, 0x1ce7 、0x19d0、0x0762、0x0255、0x0d0c、0x083b)
);
パブリック静的関数 getFormatInfo($mask, $level){
if($mask 7)
return 0;
if($level 3)
return 0;
return self::$formatInfo[$level][$mask];
}
// フレーム -------------------------------------------- -------------------
// 初期フレームのキャッシュ。
パブリック静的 $frames = array();
パブリック静的関数 putFinderPattern(&$frame, $ox, $oy){
$finder = array(
"xc1xc1xc1xc1xc1xc1xc1",
"xc1xc0xc0xc0xc0xc0xc1"
"xc1xc0xc1xc1xc1xc0xc 1"、
"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 { 背景色: 白; }
エコー '
<tt><br><br><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>echo "</tt>";
}
}
パブリック静的関数serial($frame){
return gzcompress(join("n", $frame), 9);
}
public static function unserial($code){
returnexplode("n", gzuncompress($code));
}
パブリック静的関数 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]; }
パブリック静的関数 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 {
パブリック静的関数 png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE){
$image = self::image($frame, $pixelPerPoint, $外側フレーム);
if ($filename === false) {
Header("Content-type: image/png");
ImagePng($image);
} else {
if($saveandprint===TRUE){
ImagePng($image, $filename);
header("コンテンツタイプ: 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);
クラス 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('エラー 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);壊す;
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 = 新しい 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);壊す;
QR_MODE_AN の場合: $ret = $this->encodeModeAn($version);壊す;
QR_MODE_8 の場合: $ret = $this->encodeMode8($version);壊す;
case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break;
QR_MODE_STRUCTURE の場合: $ret = $this->encodeModeStructure();壊す;
デフォルト:
ブレイク;
}
if($ret return -1;
}
return $this->bstream->size();
} catch (Exception $e) {
return -1;
}
}
};
クラス QRinput {
public $items;
プライベート $バージョン;
プライベート$レベル;
public function __construct($version = 0, $level = QR_ECLEVEL_L){
if ($version QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
throw new Exception('無効なバージョン番号' );
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を返す;
}
パブリック関数 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];
}
}
}
$parity を返します。
}
パブリック静的関数 checkModeNum($size, $data){
for($i=0; $iif((ord($data[$i]) ord('9'))){
return false;
}
}
true を返します。
}
パブリック静的関数estimateBitsModeNum($size){
$w = (int)$size / 3;
$ビット = $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
);
パブリック静的関数 lookAnTable($c){
return (($c > 127)?-1:self::$anTable[$c]);
}
パブリック静的関数 checkModeAn($size, $data){
for($i=0; $iif (self::lookAnTable(ord($data[$i])) ) == -1) {
false を返す;
}
}
true を返します。
}
パブリック静的関数estimateBitsModeAn($size){
$w = (int)($size / 2);
$ビット = $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 を返します。
}
パブリック静的関数 check($mode, $size, $data){
if($size return false;
switch($mode) {
case QR_MODE_NUM: return self::checkModeNum($size, $data);壊す;
QR_MODE_AN の場合: 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;
$前 = 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 を返します;
}
パブリック静的関数 lengthOfCode($mode, $version, $bits){
$payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
switch($mode) {
case QR_MODE_NUM:
$chunks = (int)($payload / 10);
$remain = $ペイロード - $チャンク * 10;
$サイズ = $チャンク * 3;
if($remain >= 7) {
$size += 2;
} else if($remain >= 4) {
$size += 1;
}
休憩;
QR_MODE_AN の場合:
$chunks = (int)($payload / 11);
$remain = $ペイロード - $チャンク * 11;
$サイズ = $チャンク * 2;
if($remain >= 6)
$size++;
休憩;
QR_MODE_8 の場合:
$size = (int)($payload / 8);
休憩;
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 を返します。
}
パブリック関数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 新しい例外をスローします('WRONG VERSION');
-1 を返します。
} else if($ver > $this->getVersion()) {
$this->setVersion($ver);
} else {
ブレイク;
}
}
0を返す;
}
public function appendPaddingBit(&$bstream){
$bits = $bstream->size();
$maxwords = QRspec::getDataLength($this->バージョン, $this->レベル);
$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 を返す;
}
パブリック関数 mergeBitStream(){
if($this->convertData() return null;
}
$bstream = 新しい QRbitstream();
foreach($this->items as $item) {
$ret = $bstream->append($item->bstream);
if($ret null を返す;
}
}
$bstream を返す;
}
パブリック関数 getBitStream(){
$bstream = $this->mergeBitStream();
if($bstream == null) {
return null;
}
$ret = $this->appendPaddingBit($bstream);
if($ret null を返す;
}
$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;
}
$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;
}
}
$bstream を返す;
}
パブリック関数 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;
}
パブリック静的関数 isdigitalat($str, $pos){
if ($pos >= strlen($str))
return false;
return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) }
パブリック静的関数 isalnutat($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($実行 + 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::isalnutat($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) {
break;
}
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 == '')
return 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;
}
パブリック静的関数 SplitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true){
if(is_null($string) || $string == ' ' || $string == '') {
新しい例外をスローします('空の文字列!!!');
}
$split = 新しい QRsplit($string, $input, $modeHint);
if(!$casesensitive)
$split->toUpper();
return $split->splitString();
}
}
クラス 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;
パブリック関数 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->gt;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($symsize, $gfpoly, $fcr, $prim, $nroots, $pad){
foreach(self::$items as $rs) {
if($rs->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($symsize, $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 を $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 を返す;
}
パブリック関数 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->runLength[$i-3] <) ; 0) || ($this->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;
$ヘッド = 1;
$this->runLength[$head] = 1;
} else if($x > 0) {
if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {
$head++;
$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;
$ヘッド = 1;
$this->runLength[$head] = 1;
} else if($y > 0) {
if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {
$頭++;
$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 = 配列(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;
$黒人 = 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);
$デメリット += $this->evaluateSymbol($width, $mask);
if($デメリット $minデメリット = $デメリット;
$bestMask = $マスク;
$bestMaskNum = $i;
}
}
$bestMask を返します;
}
}
クラス 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;
}
};
//############################################## ###########################
クラス 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 新しい例外をスロー('ブロック割り当てエラー');
null を返します。
}
$this->count = 0;
}
パブリック関数 init(array $spec){
$dl = QRspec::rsDataCodes1($spec);
$el = QRspec::rsEccCodes1($spec);
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
$ブロックNo = 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;
$ブロックNo++;
}
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;
$ブロックNo++;
}
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 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 を返す;
}
}
クラス QRコード {
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 = 新しい 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;
設定解除($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 = 新しい 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 = 新しい QRinput($version, $level);

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

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

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

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

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

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

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

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


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック



