<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML LANG="ja">
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html;charset=Shift_JIS">
<TITLE>続・QR コード作成</TITLE>
</HEAD>
<BODY BGCOLOR="#CCFFFF">
<CENTER>
<BR>
<B>続・QR コード作成<BR>(Internet Explorer 5.5)</B>
<BR><BR>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=20 BGCOLOR="#FFFFFF"><TR><TD>
<DIV ID="vis" STYLE="position:relative">
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
<SCRIPT LANGUAGE="JavaScript1.2" TYPE="text/javascript">
<!--
MAX_VER = 10;
MAX_MOD = 17 + MAX_VER * 4;
for(i = 0; i < MAX_MOD; i++) {
document.write("<TR>");
for(j = 0; j < MAX_MOD; j += 4)
document.write("<TD><IMG NAME='M", i.toString(16), "_", j.toString(16), "' SRC='images/qr_m0.gif' WIDTH=12 HEIGHT=3></TD>");
document.writeln("</TR>");
}
sub = false;
//-->
</SCRIPT>
</TABLE>
</DIV>
</TD></TR></TABLE>
<BR>
<FORM>
誤り訂正レベル
<SELECT NAME="level">
<OPTION SELECTED>L
<OPTION>M
<OPTION>Q
<OPTION>H
</SELECT>
<BR><BR>
データ<BR>
<TEXTAREA NAME="data" ROWS=6 COLS=40></TEXTAREA>
<BR><BR>
<INPUT TYPE=BUTTON VALUE="作成" onClick="submit_sj()">
</FORM>
<IFRAME NAME="cd_tgt" ID="cd_tgt" WIDTH=1 HEIGHT=1 SRC="about:blank" STYLE="visibility:hidden"
onLoad="if(sub) {sub = false; QR_encoding()}"></IFRAME>
<DIV ID="msg" STYLE="visibility:hidden">処理中...</DIV>
</CENTER>
<SCRIPT LANGUAGE="JavaScript1.2" TYPE="text/javascript">
<!--
// フォーム送信
function submit_sj() {
// IE では,フォームの内容はフォームのあるページの文字コードに変換して送信されるので,
// シフト JIS のページに変換用のフォームを置く必要がある.
// このプログラムのページはシフト JIS なので,直接このページにフォームを定義してもよいが,
// このページがシフト JIS 以外の場合は,以下のようにフォームだけのページを,シフト JIS の
// 文字コード指定で作ればよい.
// このプログラムをそのままシフト JIS 以外に変換(<META HTTP-EQUIV="Content-Type" 〜 は
// 変更する)したもので,正しく QR コード作成ができることを確認済み.
with(elem_cd_tgt.contentWindow.document) {
open();
write("<BODY><FORM><INPUT TYPE=HIDDEN NAME='data'></FORM></BODY>");
close();
charset = "Shift_JIS";
// FORM で要求する URL はダミーなので,same origin ポリシーを満たせば何でもよい.
forms[0].action = location.href; // 自分自身
//forms[0].action = "dummy.txt"; // 自分と同じディレクトリにあるリソース
forms[0].data.value = document.forms[0].data.value;
sub = true;
forms[0].submit();
}
}
// エンコード
function QR_encoding() {
// データ
data = elem_cd_tgt.contentWindow.location.search;
var i1 = data.indexOf("data=");
if(i1 < 0)
return;
i1 += 5;
var i2 = data.indexOf("&", i1);
data = (i2 < 0) ? data.substring(i1) : data.substring(i1, i2);
if(!data.length)
return;
level = document.forms[0].level.selectedIndex; // 誤り訂正レベル
document.getElementById("vis").style.visibility = "hidden";
document.getElementById("msg").style.visibility = "visible";
setTimeout("QR_encoding_body(); QR_encoding_end()", 0);
}
function QR_encoding_end() {
if(data) // エラー以外
document.getElementById("vis").style.visibility = "visible";
document.getElementById("msg").style.visibility = "hidden";
}
function QR_encoding_body() {
var code1;
var n1, n2;
var b1, b2;
var x, y;
var i, j, k;
// URL デコード & モード判定
var data2 = [];
var mode; // モード
var data_len = 0; // 入力データ長
var f_num, f_alpha, f_kanji;
f_num = f_alpha = f_kanji = 1;
for(i = 0; i < data.length; ) {
switch(code1 = data.charCodeAt(i)) {
case 0x25: // %
code1 = parseInt(data.substr(i + 1, 2), 16);
if(code1 >= 0x81 && code1 <= 0x9f || code1 >= 0xe0 && code1 <= 0xfc) { // 漢字
code1 <<= 8;
var c2 = data.charCodeAt(i + 3);
if(c2 == 0x25) { // %
code1 |= parseInt(data.substr(i + 4, 2), 16);
i += 6;
}
else {
code1 |= c2;
i += 4;
}
if(code1 > 0xebbf) {
alert("エンコードできない文字があります!");
data = null;
return;
}
data2.push(code1);
data_len += 2;
f_num = f_alpha = 0;
continue;
}
i += 3;
if(code1 == 0x0a) { // LF
if(data2.length) {
if(data2[data2.length - 1] == 0x0d) { // CR
data2[data2.length - 1] = 0x0a; // LF
continue;
}
}
}
data2.push(code1);
break;
case 0x2b: // +
code1 = 0x20; // スペース
// fall thru
default:
data2.push(code1);
i++;
}
data_len++;
f_kanji = 0;
if(code1 < 0x30 || code1 > 0x39) { // 0 〜 9 以外
f_num = 0;
if(code1 < 0x41 || code1 > 0x5a) { // A 〜 Z 以外
switch(code1) {
case 0x20: // スペース
case 0x24: // $
case 0x25: // %
case 0x2a: // *
case 0x2b: // +
case 0x2d: // -
case 0x2e: // .
case 0x2f: // /
case 0x3a: // :
break;
default:
f_alpha = 0;
}
}
}
}
if (f_num)
mode = 0; // 数字モード
else if(f_alpha)
mode = 1; // 英数字モード
else if(f_kanji)
mode = 3; // 漢字モード
else
mode = 2; // 8 ビット バイト モード
var version; // 型番
var len_bits; // 文字数指示子ビット数
var data_cws; // データ コード語数
var max_chars; // 最大格納文字数
i_code = 0;
reg = 0;
reg_bits = 0;
switch(mode) {
case 0: // 数字モード
// 型番決定
for(version = 1; version <= MAX_VER; version++) {
if (version <= 9)
len_bits = 10;
else if(version <= 26)
len_bits = 12;
else
len_bits = 14;
n1 = (data_cws = get_data_cws(version, level)) * 8 - 4 - len_bits;
max_chars = Math.floor(n1 / 10) * 3;
n1 %= 10;
if(n1 >= 4) {
if(n1 >= 7)
max_chars += 2;
else
max_chars++;
}
if(data_len <= max_chars)
break;
}
if(version > MAX_VER) {
alert("データが長すぎます!");
data = null;
return;
}
// データ コード語作成
// モード指示子,文字数指示子
put_code(0x1, 4);
put_code(data_len, len_bits);
// データ
for(i = 0; ; ) {
if(i + 2 < data_len) {
put_code((data2[i] & 0x0f) * 100 + (data2[i + 1] & 0x0f) * 10 + (data2[i + 2] & 0x0f), 10);
if((i += 3) == data_len)
break;
}
else {
if (i + 1 < data_len)
put_code((data2[i] & 0x0f) * 10 + (data2[i + 1] & 0x0f), 7);
else if(i < data_len)
put_code(data2[i] & 0x0f, 4);
break;
}
}
break;
case 1: // 英数字モード
// 型番決定
for(version = 1; version <= MAX_VER; version++) {
if (version <= 9)
len_bits = 9;
else if(version <= 26)
len_bits = 11;
else
len_bits = 13;
n1 = (data_cws = get_data_cws(version, level)) * 8 - 4 - len_bits;
max_chars = Math.floor(n1 / 11) * 2;
if(n1 % 11 >= 6)
max_chars++;
if(data_len <= max_chars)
break;
}
if(version > MAX_VER) {
alert("データが長すぎます!");
data = null;
return;
}
// データ コード語作成
// モード指示子,文字数指示子
put_code(0x2, 4);
put_code(data_len, len_bits);
// データ
for(i = 0; ; ) {
if(i + 1 < data_len) {
put_code(alpha_val(data2[i]) * 45 + alpha_val(data2[i + 1]), 11);
if((i += 2) == data_len)
break;
}
else {
put_code(alpha_val(data2[i]), 6);
break;
}
}
break;
case 2: // 8 ビット バイト モード
// 型番決定
for(version = 1; version <= MAX_VER; version++) {
if (version <= 9)
len_bits = 8;
else
len_bits = 16;
max_chars = Math.floor(((data_cws = get_data_cws(version, level)) * 8 - 4 - len_bits) / 8);
if(data_len <= max_chars)
break;
}
if(version > MAX_VER) {
alert("データが長すぎます!");
data = null;
return;
}
// データ コード語作成
// モード指示子,文字数指示子
put_code(0x4, 4);
put_code(data_len, len_bits);
// データ
for(i = 0; i < data2.length; i++)
put_code(data2[i], (data2[i] & 0xff00) ? 16 : 8);
break;
case 3: // 漢字モード
data_len >>= 1;
// 型番決定
for(version = 1; version <= MAX_VER; version++) {
if (version <= 9)
len_bits = 8;
else if(version <= 26)
len_bits = 10;
else
len_bits = 12;
max_chars = Math.floor(((data_cws = get_data_cws(version, level)) * 8 - 4 - len_bits) / 13);
if(data_len <= max_chars)
break;
}
if(version > MAX_VER) {
alert("データが長すぎます!");
data = null;
return;
}
// データ コード語作成
// モード指示子,文字数指示子
put_code(0x8, 4);
put_code(data_len, len_bits);
// データ
for(i = 0; i < data_len; i++) {
code1 = data2[i];
if(code1 < 0xe000)
code1 -= 0x8140;
else
code1 -= 0xc140;
put_code((code1 >> 8) * 0xc0 + (code1 & 0xff), 13);
}
break;
}
// 終端パターン“0000”付加
if(i_code < data_cws - 1 || i_code < data_cws && !reg_bits)
put_code(0x0, 4);
// フラッシュ
if(reg_bits)
code[i_code++] = (reg << (8 - reg_bits)) & 0xff;
// パディング
for(; ; ) {
if(i_code == data_cws)
break;
code[i_code++] = 0xec;
if(i_code == data_cws)
break;
code[i_code++] = 0x11;
}
var n_blocks = rs_blocks[version - 1][level]; // RS ブロック数
var n_ec = ec_codewords[version - 1][level]; // 誤り訂正コード語数
var g_exp = g_exp_t[n_ec - 1]; // 誤り訂正コード α指数
// 誤り訂正コード作成
var i_data = 0;
var i_ec = data_cws;
n1 = Math.floor(data_cws / n_blocks);
n2 = n_blocks - data_cws % n_blocks;
for(i_block = 0; i_block < n_blocks; i_block++) {
if(i_block == n2)
n1++;
var data_ec = code.slice(i_data, i_data + n1);
data_ec.length = n1 + n_ec;
for(i = 0; i < n_ec; i++)
data_ec[n1 + i] = 0;
for(i = 0; i < n1; i++) {
if(data_ec[i]) {
var exp1 = n_exp[data_ec[i]];
for(j = 0; j < n_ec; j++)
data_ec[i + 1 + j] ^= exp_n[(g_exp[j] + exp1) % 255];
}
}
for(i = 0; i < n_ec; i++)
code[i_ec + i] = data_ec[n1 + i];
i_data += n1;
i_ec += n_ec;
}
var n_modules1 = 21 + (version - 1) * 4; // 1 辺のモジュール数
for(i = 0; i < n_modules1; i++) {
for(j = 0; j < n_modules1; j++)
module1[i][j] = 0;
}
// 位置検出パターン & 分離パターン & 形式情報位置予約(一部)& 固定暗モジュール
for(i = 0; i < 8; i++) {
for(j = 0; j < 9; j++) // 左上
module1[i][j] = finder_pat[i + 1][1 + j];
for(j = 0; j < 8; j++) // 右上
module1[i][n_modules1 - 8 + j] = finder_pat[i + 1][j];
for(j = 0; j < 9; j++) // 左下
module1[n_modules1 - 8 + i][j] = finder_pat[i][1 + j];
}
// 形式情報位置予約
module1[8].splice(0, 9, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40);
module1[8].splice(n_modules1 - 8, 8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40);
// 型番情報位置予約
if(version >= 7) {
for(i = 11; i >= 9; i--) // 左下
module1[n_modules1 - i].splice(0, 6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40);
for(i = 0; i <= 5; i++) // 右上
module1[i].splice(n_modules1 - 11, 3, 0x40, 0x40, 0x40);
}
// タイミング パターン
for(i = 8; i < n_modules1 - 9; i += 2) {
module1[6][i ] = module1[i ][6] = 0x81;
module1[6][i + 1] = module1[i + 1][6] = 0x80;
}
module1[6][i] = module1[i][6] = 0x81;
// 位置合せパターン
n1 = align_pos[version - 1].length;
for(i = 0; i < n1; i++) {
y = align_pos[version - 1][i];
for(j = 0; j < n1; j++) {
if(i == 0 && j == 0 || i == 0 && j == n1 - 1 || i == n1 - 1 && j == 0)
continue;
x = align_pos[version - 1][j];
module1[y - 2].splice(x - 2, 5, 0x81, 0x81, 0x81, 0x81, 0x81);
module1[y - 1].splice(x - 2, 5, 0x81, 0x80, 0x80, 0x80, 0x81);
module1[y ].splice(x - 2, 5, 0x81, 0x80, 0x81, 0x80, 0x81);
module1[y + 1].splice(x - 2, 5, 0x81, 0x80, 0x80, 0x80, 0x81);
module1[y + 2].splice(x - 2, 5, 0x81, 0x81, 0x81, 0x81, 0x81);
}
}
// シンボル キャラクタ配置
n1 = Math.floor(data_cws / n_blocks);
n2 = n_blocks - data_cws % n_blocks;
i_block = 0;
i_code = 0;
code1 = code[0];
b1 = 0x80;
i = j = n_modules1 - 1;
var dir = 0; // 走査方向
var l_r = 0; // 右/左
for(; ; ) {
if(!module1[i][j]) { // 空き
module1[i][j] = (code1 & b1) ? 1 : 0;
if(!(b1 >>= 1)) {
// 次のコード語
if(++i_block == n_blocks) {
i_block = 0;
i_code++;
if(n1) { // データ コード
if (i_code == n1) { // 短い方のデータ コードの長さ分終了
if(n2 == n_blocks) { // データ コードの長さがすべて等しい → 誤り訂正コードへ
n1 = 0;
i_code = 0;
}
else { // 余り分
i_block = n2;
}
}
else if(i_code > n1) { // データ コード終了 → 誤り訂正コードへ
n1 = 0;
i_code = 0;
}
}
else { // 誤り訂正コード
if(i_code == n_ec) // 終了
break;
}
}
if(n1) { // データ コード
k = i_block * n1;
if(i_block > n2)
k += i_block - n2;
}
else { // 誤り訂正コード
k = data_cws + i_block * n_ec;
}
code1 = code[k + i_code];
b1 = 0x80;
}
}
if(l_r) { // 左
if(dir) { // 下方向
if(i < n_modules1 - 1) {
i++;
j++;
}
else {
dir = 0; // 反転
if(--j == 6)
j = 5;
}
}
else { // 上方向
if(i) {
i--;
j++;
}
else {
dir = 1; // 反転
if(--j == 6)
j = 5;
}
}
l_r = 0;
}
else { // 右
j--;
l_r = 1;
}
}
// マスク パターン決定
var mask; // マスク パターン
var min_penalty = 0x7fffffff; // 最小失点
var m;
for(m = 0x0; m <= 0x7; m++) {
masking(n_modules1, m); // マスク
// 失点計算
var penalty = 0; // 失点
// 同色の隣接モジュール
for(i = 0; i < n_modules1; i++) {
// 行
b1 = module2[i][0];
n1 = 1;
// 列
b2 = module2[0][i];
n2 = 1;
for(j = 1; j < n_modules1; j++) {
// 行
if(module2[i][j] == b1) {
n1++;
}
else {
if(n1 >= 5)
penalty += 3 + (n1 - 5);
b1 = module2[i][j];
n1 = 1;
}
// 列
if(module2[j][i] == b2) {
n2++;
}
else {
if(n2 >= 5)
penalty += 3 + (n2 - 5);
b2 = module2[j][i];
n2 = 1;
}
}
// 行
if(n1 >= 5)
penalty += 3 + (n1 - 5);
// 列
if(n2 >= 5)
penalty += 3 + (n2 - 5);
}
// 2×2 のモジュール ブロック
for(i = 0; i < n_modules1 - 1; i++) {
for(j = 0; j < n_modules1 - 1; j++) {
b1 = module2[i][j];
if(module2[i][j + 1] == b1 && module2[i + 1][j] == b1 && module2[i + 1][j + 1] == b1)
penalty += 3;
}
}
// 1:1:3:1:1 比率のパターン
var cnt = new Array();
cnt.length = 7;
// 行
for(i = 0; i < n_modules1; i++) {
k = 0;
for(j = 0; ; ) {
// 同色モジュール数カウント
for(; k < 7; k++) {
x = j;
for(; j < n_modules1; j++) {
if(module2[i][j] ^ (k & 0x01)) // k = 0,2,4,6 -- 暗?,k = 1,3,5 -- 明?
break;
}
cnt[k] = j - x; // モジュール数
if(j == n_modules1)
break;
}
if(k >= 5) {
if(k == 5)
cnt[6] = 0;
if(cnt[2] == cnt[1] && cnt[3] == cnt[1] * 3 && cnt[4] == cnt[1] && cnt[5] == cnt[1]
&& (cnt[0] >= cnt[1] * 4 || cnt[6] >= cnt[1] * 4)) { // 1:1:3:1:1 & 4 以上の明
penalty += 40;
if(j < n_modules1) { // 終端でない
// 続きをチェック
cnt[0] = cnt[4];
cnt[1] = cnt[5];
cnt[2] = cnt[6];
k = 3;
continue;
}
}
}
if(j == n_modules1)
break;
// 続きをチェック
cnt[0] = cnt[2];
cnt[1] = cnt[3];
cnt[2] = cnt[4];
cnt[3] = cnt[5];
cnt[4] = cnt[6];
k = 5;
}
}
// 列
for(j = 0; j < n_modules1; j++) {
k = 0;
for(i = 0; ; ) {
// 同色モジュール数カウント
for(; k < 7; k++) {
y = i;
for(; i < n_modules1; i++) {
if(module2[i][j] ^ (k & 0x01)) // k = 0,2,4,6 -- 暗?,k = 1,3,5 -- 明?
break;
}
cnt[k] = i - y; // モジュール数
if(i == n_modules1)
break;
}
if(k >= 5) {
if(k == 5)
cnt[6] = 0;
if(cnt[2] == cnt[1] && cnt[3] == cnt[1] * 3 && cnt[4] == cnt[1] && cnt[5] == cnt[1]
&& (cnt[0] >= cnt[1] * 4 || cnt[6] >= cnt[1] * 4)) { // 1:1:3:1:1 & 4 以上の明
penalty += 40;
if(i < n_modules1) { // 終端でない
// 続きをチェック
cnt[0] = cnt[4];
cnt[1] = cnt[5];
cnt[2] = cnt[6];
k = 3;
continue;
}
}
}
if(i == n_modules1)
break;
// 続きをチェック
cnt[0] = cnt[2];
cnt[1] = cnt[3];
cnt[2] = cnt[4];
cnt[3] = cnt[5];
cnt[4] = cnt[6];
k = 5;
}
}
// 暗モジュール比率
// 2004年改正 JIS X 0510 では「参考」にある例が「評価条件」と矛盾している.
n1 = 0;
for(i = 0; i < n_modules1; i++) {
for(j = 0; j < n_modules1; j++) {
if(module2[i][j]) // 暗
n1++;
}
}
n2 = n_modules1 * n_modules1;
if((n1 = Math.floor((Math.abs(n1 * 2 - n2) * 20 + (n2 * 2) - 1) / (n2 * 2))) > 1)
penalty += 10 * (n1 - 1);
if(penalty < min_penalty) {
mask = m;
min_penalty = penalty;
}
}
masking(n_modules1, mask); // 採用したマスク パターンでマスク
// 固定暗モジュール
// 固定暗モジュール配置はマスク判定の前か後か?
module2[n_modules1 - 8][8] = 1;
// 形式情報
code1 = format_info[level][mask];
b1 = 0x4000;
for(i = 0; i < 7; i++) {
module2[8][(i < 6) ? i : i + 1] = module2[n_modules1 - 1 - i][8] = (code1 & b1) ? 1 : 0;
b1 >>= 1;
}
for(i = 7; i >= 0; i--) {
module2[(i < 6) ? i : i + 1][8] = module2[8][n_modules1 - 1 - i] = (code1 & b1) ? 1 : 0;
b1 >>= 1;
}
// 型番情報
if(version >= 7) {
code1 = version_info[version - 7];
b1 = 0x20000;
for(i = 0; i < 18; i++) {
y = n_modules1 - 9 - i % 3;
x = 5 - Math.floor(i / 3);
module2[y][x] = module2[x][y] = (code1 & b1) ? 1 : 0;
b1 >>= 1;
}
}
// 表示
for(i = 0; i < n_modules1; i++) {
for(j = 0; j < n_modules1; j += 4) {
k = (module2[i][j]) ? 0x8 : 0;
if(j + 1 < n_modules1)
k |= (module2[i][j + 1]) ? 0x4 : 0;
if(j + 2 < n_modules1)
k |= (module2[i][j + 2]) ? 0x2 : 0;
if(j + 3 < n_modules1)
k |= (module2[i][j + 3]) ? 0x1 : 0;
document.images["M" + i.toString(16) + "_" + j.toString(16)].src = img_m[k].src;
}
for(; j < MAX_MOD; j += 4)
document.images["M" + i.toString(16) + "_" + j.toString(16)].src = img_m[0].src;
}
for(; i < MAX_MOD; i++) {
for(j = 0; j < MAX_MOD; j += 4)
document.images["M" + i.toString(16) + "_" + j.toString(16)].src = img_m[0].src;
}
}
// データ コード語数
function get_data_cws(version, level) {
var n_modules;
var n;
n_modules = 21 + (version - 1) * 4; // 1 辺のモジュール数
n_modules = n_modules * n_modules // 総モジュール数
- 3 * (8 * 8) // 位置検出パターン & 分離パターン
- 2 * (n_modules - 2 * 8) // タイミング パターン
- 1 // 固定暗モジュール
- 2 * 15; // 形式情報
// 位置合せパターン
n = align_pos[version - 1].length;
if(n) { // n > 0
n_modules -= (n * n - 3) * (5 * 5);
if(n > 2)
n_modules += 2 * (n - 2) * 5; // タイミング パターンと重なる分
}
// 型番情報
if(version >= 7)
n_modules -= 2 * 18;
return (n_modules >> 3) - rs_blocks[version - 1][level] * ec_codewords[version - 1][level];
}
// コード登録
function put_code(code1, code1_bits) {
reg = (reg << code1_bits) | code1;
reg_bits += code1_bits;
while(reg_bits >= 8) {
code[i_code++] = (reg >> (reg_bits - 8)) & 0xff;
reg_bits -= 8;
}
}
// 英数字モード 文字値
function alpha_val(c) {
switch(c) {
case 0x20: // スペース
return 36;
case 0x24: // $
return 37;
case 0x25: // %
return 38;
case 0x2a: // *
return 39;
case 0x2b: // +
return 40;
case 0x2d: // -
return 41;
case 0x2e: // .
return 42;
case 0x2f: // /
return 43;
case 0x3a: // :
return 44;
}
if(c <= 0x39)
return c & 0x0f;
return c - 0x41 + 10;
}
// マスク処理
function masking(n_modules1, mask) {
var i, j;
for(i = 0; i < n_modules1; i++) {
for(j = 0; j < n_modules1; j++) {
module2[i][j] = module1[i][j] & 0x1;
if(!(module1[i][j] & 0xc0)) { // 機能パターン,形式情報,型番情報を除く
switch(mask) {
case 0: // (i+j)mod 2=0
if((i + j) % 2)
continue;
break;
case 1: // i mod 2=0
if(i % 2)
continue;
break;
case 2: // j mod 3=0
if(j % 3)
continue;
break;
case 3: // (i+j)mod 3=0
if((i + j) % 3)
continue;
break;
case 4: // ((i div 2)+(j div 3))mod 2=0
if((Math.floor(i / 2) + Math.floor(j / 3)) % 2)
continue;
break;
case 5: // (i j)mod 2+(i j)mod 3=0
if(i * j % 2 + i * j % 3)
continue;
break;
case 6: // ((i j)mod 2+(i j)mod 3)mod 2=0
if((i * j % 2 + i * j % 3) % 2)
continue;
break;
case 7: // ((i j)mod 3+(i+j)mod 2)mod 2=0
if((i * j % 3 + (i + j) % 2) % 2)
continue;
break;
}
module2[i][j] ^= 1; // 反転
}
}
}
}
//----------------------------------------------------------
// モジュール表示用画像
img_m = new Array();
img_m.length = 16;
for(i = 0; i < 16; i++) {
img_m[i] = new Image(12, 3);
img_m[i].src = "images/qr_m" + i.toString(16) + ".gif";
}
code = new Array(); // コード語作成ワーク
code.length = 3706;
var i_code; // コード語インデックス
var reg;
var reg_bits;
// 誤り訂正コード語数
ec_codewords = [
// 誤り訂正レベル
// L M Q H 型番
[ 7, 10, 13, 17], // 1
[10, 16, 22, 28], // 2
[15, 26, 18, 22], // 3
[20, 18, 26, 16], // 4
[26, 24, 18, 22], // 5
[18, 16, 24, 28], // 6
[20, 18, 18, 26], // 7
[24, 22, 22, 26], // 8
[30, 22, 20, 24], // 9
[18, 26, 24, 28], // 10
[20, 30, 28, 24], // 11
[24, 22, 26, 28], // 12
[26, 22, 24, 22], // 13
[30, 24, 20, 24], // 14
[22, 24, 30, 24], // 15
[24, 28, 24, 30], // 16
[28, 28, 28, 28], // 17
[30, 26, 28, 28], // 18
[28, 26, 26, 26], // 19
[28, 26, 30, 28], // 20
[28, 26, 28, 30], // 21
[28, 28, 30, 24], // 22
[30, 28, 30, 30], // 23
[30, 28, 30, 30], // 24
[26, 28, 30, 30], // 25
[28, 28, 28, 30], // 26
[30, 28, 30, 30], // 27
[30, 28, 30, 30], // 28
[30, 28, 30, 30], // 29
[30, 28, 30, 30], // 30
[30, 28, 30, 30], // 31
[30, 28, 30, 30], // 32
[30, 28, 30, 30], // 33
[30, 28, 30, 30], // 34
[30, 28, 30, 30], // 35
[30, 28, 30, 30], // 36
[30, 28, 30, 30], // 37
[30, 28, 30, 30], // 38
[30, 28, 30, 30], // 39
[30, 28, 30, 30] // 40
];
// RS ブロック数
rs_blocks = [
// 誤り訂正レベル
// L M Q H 型番
[ 1, 1, 1, 1], // 1
[ 1, 1, 1, 1], // 2
[ 1, 1, 2, 2], // 3
[ 1, 2, 2, 4], // 4
[ 1, 2, 4, 4], // 5
[ 2, 4, 4, 4], // 6
[ 2, 4, 6, 5], // 7
[ 2, 4, 6, 6], // 8
[ 2, 5, 8, 8], // 9
[ 4, 5, 8, 8], // 10
[ 4, 5, 8, 11], // 11
[ 4, 8, 10, 11], // 12
[ 4, 9, 12, 16], // 13
[ 4, 9, 16, 16], // 14
[ 6, 10, 12, 18], // 15
[ 6, 10, 17, 16], // 16
[ 6, 11, 16, 19], // 17
[ 6, 13, 18, 21], // 18
[ 7, 14, 21, 25], // 19
[ 8, 16, 20, 25], // 20
[ 8, 17, 23, 25], // 21
[ 9, 17, 23, 34], // 22
[ 9, 18, 25, 30], // 23
[10, 20, 27, 32], // 24
[12, 21, 29, 35], // 25
[12, 23, 34, 37], // 26
[12, 25, 34, 40], // 27
[13, 26, 35, 42], // 28
[14, 28, 38, 45], // 29
[15, 29, 40, 48], // 30
[16, 31, 43, 51], // 31
[17, 33, 45, 54], // 32
[18, 35, 48, 57], // 33
[19, 37, 51, 60], // 34
[19, 38, 53, 63], // 35
[20, 40, 56, 66], // 36
[21, 43, 59, 70], // 37
[22, 45, 62, 74], // 38
[24, 47, 65, 77], // 39
[25, 49, 68, 81] // 40
];
// 誤り訂正コード 生成多項式係数 α指数
g_exp_t = new Array();
g_exp_t.length = 30;
g_exp_t[ 6] = [87, 229, 146, 149, 238, 102, 21];
g_exp_t[ 9] = [251, 67, 46, 61, 118, 70, 64, 94, 32, 45];
g_exp_t[12] = [74, 152, 176, 100, 86, 100, 106, 104, 130, 218, 206, 140, 78];
g_exp_t[14] = [8, 183, 61, 91, 202, 37, 51, 58, 58, 237, 140, 124, 5, 99, 105];
g_exp_t[15] = [120, 104, 107, 109, 102, 161, 76, 3, 91, 191, 147, 169, 182, 194, 225, 120];
g_exp_t[16] = [43, 139, 206, 78, 43, 239, 123, 206, 214, 147, 24, 99, 150, 39, 243, 163, 136];
g_exp_t[17] = [215, 234, 158, 94, 184, 97, 118, 170, 79, 187, 152, 148, 252, 179, 5, 98, 96, 153];
g_exp_t[19] = [17, 60, 79, 50, 61, 163, 26, 187, 202, 180, 221, 225, 83, 239, 156, 164, 212, 212, 188, 190];
g_exp_t[21] = [210, 171, 247, 242, 93, 230, 14, 109, 221, 53, 200, 74, 8, 172, 98, 80, 219, 134, 160, 105, 165, 231];
g_exp_t[23] = [229, 121, 135, 48, 211, 117, 251, 126, 159, 180, 169, 152, 192, 226, 228, 218, 111, 0, 117, 232, 87, 96, 227, 21];
g_exp_t[25] = [173, 125, 158, 2, 103, 182, 118, 17, 145, 201, 111, 28, 165, 53,161, 21, 245, 142, 13, 102, 48, 227, 153, 145, 218, 70];
g_exp_t[27] = [168, 223, 200, 104, 224, 234, 108, 180, 110, 190, 195, 147, 205, 27, 232, 201, 21, 43, 245, 87, 42, 195, 212, 119, 242, 37, 9, 123];
g_exp_t[29] = [41, 173, 145, 152, 216, 31, 179, 182, 50, 48, 110, 86, 239, 96, 222, 125, 42, 173, 226, 193, 224, 130, 156, 37, 251, 216, 238, 40, 192, 180];
// 位置検出パターン & 分離パターン & 形式情報位置予約(一部)& 固定暗モジュール用データ
finder_pat = [
// [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x41],
[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40],
[0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x80, 0x81, 0x81, 0x81, 0x80, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x80, 0x40],
[0x80, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x40],
[0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40]
];
// 位置合せパターン座標
align_pos = [
// 型番
[], // 1
[ 6, 18], // 2
[ 6, 22], // 3
[ 6, 26], // 4
[ 6, 30], // 5
[ 6, 34], // 6
[ 6, 22, 38], // 7
[ 6, 24, 42], // 8
[ 6, 26, 46], // 9
[ 6, 28, 50], // 10
[ 6, 30, 54], // 11
[ 6, 32, 58], // 12
[ 6, 34, 62], // 13
[ 6, 26, 46, 66], // 14
[ 6, 26, 48, 70], // 15
[ 6, 26, 50, 74], // 16
[ 6, 30, 54, 78], // 17
[ 6, 30, 56, 82], // 18
[ 6, 30, 58, 86], // 19
[ 6, 34, 62, 90], // 20
[ 6, 28, 50, 72, 94], // 21
[ 6, 26, 50, 74, 98], // 22
[ 6, 30, 54, 78, 102], // 23
[ 6, 28, 54, 80, 106], // 24
[ 6, 32, 58, 84, 110], // 25
[ 6, 30, 58, 86, 114], // 26
[ 6, 34, 62, 90, 118], // 27
[ 6, 26, 50, 74, 98, 122], // 28
[ 6, 30, 54, 78, 102, 126], // 29
[ 6, 26, 52, 78, 104, 130], // 30
[ 6, 30, 56, 82, 108, 134], // 31
[ 6, 34, 60, 86, 112, 138], // 32
[ 6, 30, 58, 86, 114, 142], // 33
[ 6, 34, 62, 90, 118, 146], // 34
[ 6, 30, 54, 78, 102, 126, 150], // 35
[ 6, 24, 50, 76, 102, 128, 154], // 36
[ 6, 28, 54, 80, 106, 132, 158], // 37
[ 6, 32, 58, 84, 110, 136, 162], // 38
[ 6, 26, 54, 82, 110, 138, 166], // 39
[ 6, 30, 58, 86, 114, 142, 170] // 40
];
// 形式情報
format_info = [
// Level + Mask BCH 符号(マスク前)
[0x77c4, // L + 000 0x23d6
0x72f3, // L + 001 0x26e1
0x7daa, // L + 010 0x29b8
0x789d, // L + 011 0x2c8f
0x662f, // L + 100 0x323d
0x6318, // L + 101 0x370a
0x6c41, // L + 110 0x3853
0x6976], // L + 111 0x3d64
[0x5412, // M + 000 0x0000
0x5125, // M + 001 0x0537
0x5e7c, // M + 010 0x0a6e
0x5b4b, // M + 011 0x0f59
0x45f9, // M + 100 0x11eb
0x40ce, // M + 101 0x14dc
0x4f97, // M + 110 0x1b85
0x4aa0], // M + 111 0x1eb2
[0x355f, // Q + 000 0x614d
0x3068, // Q + 001 0x647a
0x3f31, // Q + 010 0x6b23
0x3a06, // Q + 011 0x6e14
0x24b4, // Q + 100 0x70a6
0x2183, // Q + 101 0x7591
0x2eda, // Q + 110 0x7ac8
0x2bed], // Q + 111 0x7fff
[0x1689, // H + 000 0x429b
0x13be, // H + 001 0x47ac
0x1ce7, // H + 010 0x48f5
0x19d0, // H + 011 0x4dc2
0x0762, // H + 100 0x5370
0x0255, // H + 101 0x5647
0x0d0c, // H + 110 0x591e
0x083b] // H + 111 0x5c29
];
// 型番情報
// 型番
version_info = [0x07c94, // 7
0x085bc, // 8
0x09a99, // 9
0x0a4d3, // 10
0x0bbf6, // 11
0x0c762, // 12
0x0d847, // 13
0x0e60d, // 14
0x0f928, // 15
0x10b78, // 16
0x1145d, // 17
0x12a17, // 18
0x13532, // 19
0x149a6, // 20
0x15683, // 21
0x168c9, // 22
0x177ec, // 23
0x18ec4, // 24
0x191e1, // 25
0x1afab, // 26
0x1b08e, // 27
0x1cc1a, // 28
0x1d33f, // 29
0x1ed75, // 30
0x1f250, // 31
0x209d5, // 32
0x216f0, // 33
0x228ba, // 34
0x2379f, // 35
0x24b0b, // 36
0x2542e, // 37
0x26a64, // 38
0x27541, // 39
0x28c69]; // 40
exp_n = new Array(); // α指数 → 数値 変換テーブル
exp_n.length = 255;
n_exp = new Array(); // 数値 → α指数 変換テーブル([0] は使用しない)
n_exp.length = 256;
// α指数 ― 数値 変換テーブル作成
n = 0x01;
for(i = 0; i < 255; i++) {
exp_n[i] = n;
n_exp[n] = i;
n <<= 1;
if(n & 0x100)
n = n & 0xff ^ 0x1d;
}
module1 = new Array(); // シンボル領域
module1.length = MAX_MOD;
module2 = new Array(); // マスク後シンボル領域
module2.length = MAX_MOD;
for(i = 0; i < MAX_MOD; i++) {
module1[i] = new Array();
module1[i].length = MAX_MOD;
module2[i] = new Array();
module2[i].length = MAX_MOD;
}
elem_cd_tgt = document.getElementById("cd_tgt");
//-->
</SCRIPT>
</BODY>
</HTML>
|