QR コードは明暗のセルが並んだ図で、中身はバイト列です。リンクそのものではありません。読み取り側は、画像から記号を見つけ、傾きと倍率を補正し、決まった順にセルを読み、マスクを外し、Reed–Solomon の誤り訂正碼を検算して、バイト列を返します。この記事に挙がる失敗の多くは、どれか一つの段階で止まった結果です。

QR コードは 1994 年にデンソーウェーブが発表しました(デンソーウェーブ「QRコード道のり」)。当時から漢字やカナを表現したいという要望があり、今の仕様にも漢字モードが残っています。当サイトのQRコード読み取りは、ZXing C++ を WebAssembly にした zxing-wasm でこの処理をページ内で行います。以下では、図形の構成、誤り訂正ごとの容量、文字コードの決まり方、Wi-Fi や vCard の読み方、失敗する条件を順に見ます。

図形の中身:位置検出、タイミング、アライメント、余白

記号の構造は ISO/IEC 18004:2006 が定めています。データ以外にも固定の図形があります。

  • 位置検出パターン。 左上・右上・左下にある 7×7 の四角です。読み取り側はこれで記号の位置と回転を知ります。右下にはなく、この非対称性で向きが分かります。
  • タイミングパターン。 6 行目と 6 列目にある、明暗が交互に並ぶ列です。位置検出パターンの間のセル数を数えるために使います。
  • アライメントパターン。 バージョン 2 以降に現れる 5×5 の四角で、記号の内側に配置されます。バージョン 1 にはありません。斜めから撮った写真の歪みを補正します。
  • 形式情報。 誤り訂正レベルとマスクの種類を、位置検出パターンの近くに 2 か所書きます。片方が壊れても読めるようにするためです。
  • データと誤り訂正のコード語。 残りの領域にジグザグ順で入り、マスクパターンと XOR されます。

さらに外周に**余白(クワイエットゾーン)**が要ります。四辺とも 4 セル幅の明るい余白です(ISO/IEC 18004:2006 §5.3.7)。余白がないと、隣の濃い文字や写真の縁を記号の一部と誤認することがあります。QR コードを文字や写真の縁にぴったり付けたときに読めず、白い余白を足すと読めるのはこのためです。

大きさはバージョンで表します。バージョン 1 は 21×21 セルで、1 版上がるごとに一辺が 4 セル増え、バージョン 40 で 177×177 になります。

バージョンセル数当サイトの生成ツールでの例
121×21誤り訂正 L での短い大文字 URL
225×25誤り訂正 M での https://zerotool.dev
537×37同じ連絡先の MECARD 形式
849×49同じ連絡先の vCard 3.0 形式
40177×177誤り訂正 L での最大容量

4 つのモードと 1 文字あたりのコスト

QR コードは文字をそのまま入れるのではなく、内容をいくつかのセグメントに分け、それぞれにモードを選びます。

モード使える文字コスト
数字0–93 桁あたり 10 ビット
英数字0–9、A–Z、空白と $ % * + - . / :2 文字あたり 11 ビット
バイト任意のバイト1 バイトあたり 8 ビット
漢字JIS X 0208 の文字1 文字あたり 13 ビット

1 つの記号の中で、セグメントの境目にモードを切り替えられます(ISO/IEC 18004:2006 §6.3.6)。ホスト名が大文字、パスが小文字の URL が英数字とバイトの混在になるのはこのためです。生成ツールは総ビット数が最小になる分割を選び、状態欄に表示します。

QRコード作成の実測例を 3 つ挙げます。

  • https://zerotool.dev を誤り訂正 M で作るとバージョン 2、25×25 セル、データ 224 ビットのうち 172 ビット(77%)。バイトモードで 20 バイトです。
  • HTTPS://ZEROTOOL.DEV は誤り訂正 L でバージョン 1、21×21。大文字は英数字モードに入るためです。小文字に戻すとバージョン 2 が要ります。スキームとホストは大文字小文字を区別しないので(RFC 3986 §3.1、§3.2.2)、パスの最初の / まではこの置き換えが安全です。パスとクエリは大文字小文字を区別する場合があります。
  • 2,400 文字の平文を誤り訂正 M で入れると 19,220 データビットが必要で、バージョン 40 の M は 18,672 ビットしか入らず、69 バイト超過します。同じ内容は L なら入ります。生成ツールは収めるために文章を切り詰めません。

日本語、中国語、韓国語はふつう UTF-8 で 1 文字 3 バイト、基本多言語面の外の文字は 4 バイトです。バイトモードの 2,953 は文字数ではなくバイト数です。

バージョン、誤り訂正、容量

誤り訂正は 4 段階で、失っても復元できるコード語の割合で説明されます。

レベル復元できるコード語の目安向く用途
L7%きれいな画面、短いリンク
M15%一般の既定
Q25%手に触れる印刷物、傷みやすい面
H30%小さい印刷、ロゴ入り、産業用ラベル

コード語は GF(256) 上の Reed–Solomon 符号で計算し、ブロックに分けて交互に並べます。1 本の傷が 1 ブロック全体を壊さないようにするためです。誤り訂正は壊れたコード語を戻す仕組みで、暗号化ではありません。レベルを超えた破損は復元できません。

レベルを上げると誤り訂正のコード語が増えるため、同じ文章でも大きいバージョンが必要になります。記号が密になれば、印刷や撮影で 1 セルあたりのピクセル数も増やさなければならず、利点が相殺されることがあります。まず表面に合わせてレベルを決め、そのあと実際の印刷サイズを確認します。

バージョン 40、レベル L の上限は次のとおりです。

モード容量
数字7,089 桁
英数字4,296 文字
バイト2,953 バイト
漢字1,817 文字

これは単一モードの最大値です。和英混在なら上のセグメント単価で計算するので、実際に入る量は少なくなります。

ECI と文字コード

QR コードが保存するのはバイト列です。文字コードは ECI(Extended Channel Interpretation)ヘッダーで宣言できます(ISO/IEC 18004)。代表的な割り当ては ECI 20 が Shift_JIS、ECI 26 が UTF-8 です。読み取り側はほかに Big5、GB2312、GBK、GB18030、EUC-KR、ISO-8859 系も扱います。

多くの生成ツールは ECI を書きません。2006 年版の規格はバイトモードの既定を ISO/IEC 8859-1 としていますが、実際には UTF-8 のバイト列を宣言なしで入れるツールが珍しくありません。読み取り側は次の順で判断します。

  1. ECI があればその文字コードで読み、UTF-8(ECI 26)のように表示する。
  2. ECI がなく、UTF-8 として正しければ UTF-8 で読む。
  3. そうでなければ、ページの言語の旧文字コードを先に試す。日本語ページなら Shift_JIS、中国語ページなら GB18030、韓国語ページなら EUC-KR。
  4. それでもだめなら ZXing の推定規則に従う。BOM があれば UTF-16、次に Shift_JIS、最後に ISO-8859-1。

推定した結果には「推定」と付きます。「文字コード」メニューで同じバイト列を UTF-8、Shift_JIS、GB18030/GBK、Big5、EUC-KR、ISO-8859-1、UTF-16BE、UTF-16LE で読み直せます。どの文字コードでも文字にならないバイト列は「バイナリ」として 16 進で表示します。

当サイトで確認した例です。

  • Shift_JIS のバイト列で作った 東京都千代田区丸の内 カフェ は正しく表示され、「Shift_JIS(推定)」と付きました。
  • GBK の 你好,世界。二维码测试 は英語ページでは ISO-8859-1 と推定され(ZXing と同じ挙動)、メニューで GB18030 を選ぶと正しく戻りました。

日本語の実務では、古い業務システムが Shift_JIS のまま QR コードを作り、ECI を書いていない例があります。スマートフォンのアプリが UTF-8 として読むと文字化けします。まずこのページで文字コードを選んで原文を確認し、必要なら UTF-8 で作り直します。

ブラウザーが画像を読む流れ

ページは zxing-wasm 3.1.4 を使います。ZXing C++ を WebAssembly にしたもので、スクリプトとモジュールは当サイトの /vendor から読み込み、CDN は使いません。初回だけダウンロードが発生し、gzip で約 420 KB、非圧縮で合計約 967 KiB です。転送量は圧縮とキャッシュによります。

デコードはページ内で完結します。ファイル、貼り付けたスクリーンショット、カメラのフレームについて、画像のバイト列を当サイトへアップロードしません。ただしこれはデコード経路の話です。ページは解析タグと広告も読み込み、URL モードでは入力したアドレスへ画像を取りに行きます。ページの外に出る通信は「プライバシー」の節に分けて書きます。

読み取り側の動きは次のとおりです。

  • 1 枚から最大 16 個のコードを読み、左上から行順に番号を付けます。プレビューに描く番号は結果カードと一致します。
  • QR、Micro QR、rMQR を読みます。
  • 白黒反転、回転、余白がほとんどないコードも試します。
  • 元の解像度で最大 16,777,216 ピクセルまで処理します。それを超える画像は縮小し、状態欄にその旨を出します。ブラウザー自身のキャンバス制限は端末とバージョンで変わります。
  • 画像はページ内に留めます。カメラは getUserMedia を使い、背面カメラを優先し、フレームを端末内でデコードします。

2026-09-30 の実測では、33 セルのコードは 45×45 ピクセルで読めず、60×60 で読めました。1 セルあたり約 1.5 画像ピクセルが目安です。4000×3000 のスマートフォン写真に小さいコードが写る場合、デスクトップ版 Chromium で約 1.2 秒でした。

Wi-Fi、連絡先、メール、SMS、位置情報の解析

デコードしたバイト列はテキストで、先頭の数文字でアプリの扱いが決まります。読み取り側も同じ接頭辞で項目に分け、1 行の文字列のままにしません。

接頭辞解釈根拠
http:// または https://URL。実際のホストと警告を表示—
WIFI:ネットワーク名、パスワード、暗号化方式、非表示かどうかZXing: Barcode Contents
BEGIN:VCARDvCard の連絡先RFC 2426(1998 年 9 月)
MECARD:NTT ドコモの簡易連絡先形式ドコモの項目表
mailto:宛先、Cc、件名、本文RFC 6068(2010 年 10 月)
tel:電話番号RFC 3966(2004 年 12 月)
sms: または SMSTO:番号と本文RFC 5724(2010 年 1 月)。SMSTO: は ZXing の形式
geo:緯度、経度、高度、地図リンクRFC 5870(2010 年 6 月)
その他の scheme:テキストのみ。アプリが必要と注記—

Wi-Fi の中身は 1 行のテキストです。WIFI:T:WPA;S:ゲスト用Wi-Fi;P:パスワード;; のように書きます。ZXing は \、;、,、"、: をバックスラッシュで逃がし、Android の解析コードがそのバックスラッシュを外します。Wi-Fi Alliance は同じ URI を WPA3 Specification v3.5 の 7 節に取り込み、パスワードのあるネットワークはすべて T:WPA、R:1 は WPA3-Personal 専用を表します。WiFi QRコード作成はこの形式で作り、描く前に項目の長さを検査します。読み取り側は項目を分けるだけで、代理で接続はしません。

連絡先はテキストの塊です。RFC 2426 のエスケープ規則に従い、読み取り側は名前、会社、電話、メール、住所、URL、メモを項目ごとに表示します。MECARD:N:山田,太郎;SOUND:ヤマダ,タロウ;TEL:0312345678;EMAIL:taro@example.jp;; なら、名前、よみがな、電話、メールの 4 行になります。MECARD は短い代わりに会社名と役職の欄がありません。

mailto:、tel:、sms:、geo: はそれぞれの RFC に従って項目を分けます。読み取り側はメールクライアントを開かず、発信も、SMS の送信も、ナビの起動もしません。リンクになるのは http と https だけで、しかもクリックしたときだけです。javascript:、data:、vbscript:、file: はテキストとして表示し、警告を付けます。

店舗や公共施設の Wi-Fi を QR コードで配る場合、総務省の「公衆Wi-Fi提供者向け セキュリティ対策の手引き」(令和7年2月版)は WPA2 か WPA3 を使うこと、暗号化キーを掲示して誰でも知りうる状態にすると盗聴や偽アクセスポイントのリスクが高まることを挙げています。コードを貼る場所と、キーを配る範囲は分けて考えます。

リンクを開く前に見るべき点は 2 つあり、どちらも読み取り側が指摘します。

  • https://citypark.example.gov@pay-meter.example.net/zone/4471 は自治体のドメインに見えます。@ の前はユーザー名で、ホスト行には pay-meter.example.net と出ます。
  • https://exаmple.com/login の а はキリル文字です。ホストは xn--exmple-4nf.com と表示され、似た文字への注意が出ます。

読み取れないとき

すべての画像を読める読み取り器はありません。失敗したときは、原因が元の画像に見えていることが多いです。

  • 1 セルあたりのピクセルが足りない。 33 セルのコードは 45×45 ピクセルで失敗し、60×60 で読めました。1 セル約 1.5 ピクセルが目安です。大きい写真から小さいコードを切り抜く場合、切り抜いたあとに解像度が残っている必要があります。
  • ぶれと映り込み。 手ぶれ、レンズの指紋、コードに重なる反射は明暗差を消します。角度を変えて撮り直すと読めることがあります。
  • コントラストが低い。 グレー地にグレーのコードは読めても、色あせた印刷は読めないことがあります。生成ツールは輝度差が 40% を下回ると警告します。ISO/IEC 15415 のシンボルコントラスト C 級の下限です。
  • 白黒反転。 黒地に白のコードは規格が認めていて(反射反転、§5.2)、zxing-cpp も読みますが、スマートフォンのアプリによっては反転画像を試しません。本ページで読めてスマートフォンで読めないときは、反転が候補になります。
  • 1 枚に複数のコード。 最大 16 個まで処理しますが、重なっている、画像の縁で切れている、別のコードの上に印刷されている場合は、どれも読めないことがあります。
  • 誤り訂正の上限を超えた破損。 H 級でもコード語の約 30% までです。大きいロゴや欠けた角があるコードは、読めることも読めないこともあります。
  • 文字コードの推定違い。 これは文字化けであって、デコード失敗ではありません。バイト列は読めていて、文字コードが違うだけです。
  • ブラウザーが表示できない形式。 PDF は先にスクリーンショットを撮ります。HEIC は表示できるブラウザー(通常は Safari)でだけ読めます。
  • URL モードの CORS。 画像のアドレスを渡す場合、そのサーバーがクロスオリジン要求を許可している必要があります。許可がなければ画像を保存してからドロップします。

ここで読めないときは、より鮮明な元画像、より狭い範囲の切り抜き、別の読み取り器を試してから、コード自体が無効だと判断してください。どの読み取り器でも読めないコードは存在します。1 つの読み取り器だけが読めないコードはよくあります。

プライバシー:ページの外に出る通信

ローカルファイル、貼り付けたスクリーンショット、カメラのフレームは、ページ内でデコードします。画像と解読したテキストを当サイトへアップロードせず、ブラウザーの保存領域にも書きません。デコーダーのスクリプトと WebAssembly モジュールは初回に当サイトの /vendor から読み込むため、その要求にはネットワークが必要です。「クリア」または Ctrl/⌘+L で結果を消し、カメラを停止します。

デコードとは別に、次の通信があります。

  • URL モードは入力したアドレスへ画像を取りに行きます。Cookie もリファラーも付けません。画像のサーバーには要求が見え、そのサーバーのログ方針が適用されます。
  • 解読したリンク、地図、メールアドレス、電話番号、SMS を開くと、その宛先に接続するか、設定済みのアプリが起動します。
  • ページは Google Analytics と AdSense を読み込みます。 解析タグは通常のページ情報と端末情報を集め、ツールのイベント(カメラ要求、画像の出所、結果の種類、文字コードの変更、リンクを開いたこと)を記録します。イベントに画像や解読したテキストは含まれません。コピーのイベントは、現在の結果のコピーに成功したときだけ記録します。

解読した内容はタブが開いている間ページ内に残りますが、このページはオフライン専用のリーダーではありません。デコーダー、解析タグ、広告を読み込みます。Network パネルで実際の要求を確認でき、URL モードとリンクの警告が、ブラウザーの外に出る通信を説明します。

生成・印刷・確認

読み取りと生成は同じ規格なので、生成側から見ると制限が分かりやすくなります。QRコード作成は静的コードを作ります。内容は図形の中にあり、当サイト経由のリダイレクトも有効期限もありません。

  • テキスト / URL、連絡先、メール、電話、SMS、位置のテンプレート。Wi-Fi は WiFi QRコード作成へ案内します。
  • 誤り訂正 L、M、Q、H、PNG 256〜4096 px、SVG。PNG は 1 セルが整数ピクセルです。バージョン 2 に余白を足すと 33 セル幅なので、1024 px を選ぶと 1023 px、1 セル 31 px になります。
  • 既定の余白は 4 セルです。小さくもできますが警告が出ます。
  • 容量が足りないときは、必要なビット数、入るビット数、誤り訂正を下げれば入るかを表示します。
  • 漢字モード(JIS X 0208)。既定ではオフです。すべての読み取りアプリで確認したわけではないためです。

同じ連絡先は、vCard 3.0 なら誤り訂正 M でバージョン 8(49×49)、MECARD ならバージョン 5(37×37)に入ります。ロゴの重ね合わせ、ドット柄、グラデーション、枠は用意していません。セルを覆うぶんを誤り訂正に頼ることになるためです。

印刷する前に、読む人に使ってほしいスマートフォンで書き出したファイルを読み、同じファイルをQRコード読み取りでも読んでください。テンプレートの取り違え、余白の不足、印刷サイズによる 1 セルあたりのピクセル不足が見つかります。QR コードではなくバーコードが必要なときはバーコード生成を使います。EAN-13、EAN-8、UPC-A、Code 128、Code 39、ITF-14、Codabar を作れますが、本ページの QR 読み取りはこれらを読みません。