二维码
自写编码器生成 PNG 与 SVG,容量按版本与纠错等级实时提示。
这个页面从零手写了一整套 QR Code Model 2(ISO/IEC 18004)编码器,不依赖 qrcode、bwip-js、jsqr 之类的第三方库——每一个模块、每一位校验码字都是本页自己算出来的,输入只在浏览器内存里流动,不发网络请求、不加载远程资源,也绝不出图用户没敲下的东西。写入模式支持数字(numeric)、字母数字(alphanumeric)与字节(byte)三种,"自动"会挑让位流最短的那一种;版本 1 到 40(边长 21 到 177)全覆盖,纠错等级 L/M/Q/H 对应大致 7%/15%/25%/30% 的可恢复码字。选版本与纠错的过程是把容量表当约束反查:先按模式、长度和等级从 V1 往上找第一个放得下的版本。八种掩码会逐个套到数据区上、各自算一遍罚分,取罚分最小的当选,所以同一份输入、同一版本与等级,永远得到同一张矩阵,结果完全可复现。
本页只做"生成":不接摄像头、不做扫码、也没有 WebRTC,扫描是相机 App 的事,这里如实写明、绝不假装支持。需要坦白的是不支持项:ECI、Kanji 汉字模式与结构化附录都没实现,页面上直接写明,而不是悄悄降级或假装成功。找不到放得下的版本(超过 V40 上限)就拒绝并如实报出"需要多少字节、上限是多少",而不是硬塞出一个错误的矩阵。还有一处容易看错:「SVG 模块边长」只决定导出文件的画布大小,页面上的预览恒按 6 像素/模块绘制并居中在 300px 高的画框里,改它不会动预览。
二维码怎么用
- 先填内容:把文本、URL、名片或 emoji 贴进左上的内容框(按 UTF-8 计字节),或点"生成 Wi-Fi 载荷"展开表单填 SSID / 密码 / 加密 / 是否隐藏,填好后点"填入内容框"——特殊字符会被自动转义。空输入不会出图,页面给出填写引导而不是生成一张空白码。附带一个 Wi-Fi 载荷生成器,产出 `WIFI:T:…;S:…;P:…;;`,对 : ; , " 五个字符自动加反斜杠转义。
- 再定参数:纠错等级在 L/M/Q/H 间切换(等级越高、同容量下版本越大);模式默认"自动",也可强制数字/字母数字/字节,强制后若含不合法字符会指明是第几个字符不通过。静区、SVG 模块边长(只管导出文件,预览不动)、PNG 目标边长按需调整,反色开关把深底白码互换。静区默认 4 模块(规范建议值),反色开关是给深底白码用的。
- 读结果并下载:预览下方读出版本、边长、等级、掩码、模式、数据/EC 码字数、格式位与罚分,容量行提示余量与下一版;「下载 SVG / 下载 PNG」两个按钮就在预览卡的标题行右侧(与容量行同一排),点了经 Blob + <a download> 存盘。输入停手约 150ms 后重画,纠错等级、模式、反色与 Wi-Fi 填入是即时的。本页没有复制按钮、没有收藏、不登录,输入内容不出浏览器;也不提供扫码,那是相机的工作。输出有两种:SVG 按整数模块边长画、同一行连续的深色模块合并成一条 <rect> 并标 shape-rendering="crispEdges",缩放不糊;PNG 用 canvas 按你选的目标像素边长光栅化。容量提示行的写法是"N 字节 → 版本 V(等级 X);本版还能放多少、同等级下一版还能放多少"。
- 三种模式各自怎么压位:纯 0-9 走数字模式,每 3 位压成 10 bit;集合 `0-9 A-Z 空格 $%*+-./:` 内走字母数字模式,每 2 个字符按 45 进制压成 11 bit;其余一律走字节模式,字符串先按 UTF-8 编码再按字节计容量——这也是汉字、emoji 与大小写混排的文本必然跳更高分区版本的原因。
常见问题
同样 10 个字,为什么中文或 emoji 比英文字母要更大的版本?
因为容量按 UTF-8 字节数算,不按"字数"。ASCII 字母一个字符 1 字节,汉字常见 3 字节,emoji 多为 4 字节;同样 10 个字符,中文可能占 30 字节,需要的版本与纠错码字自然更多。页面读出的"载荷"一项在字节模式下显示的就是编码后的字节数,你换等级或换模式时它会同步变化。
版本号和掩码是怎么定下来的?换台浏览器会不一样吗?
版本是"能装下当前长度与等级的最小版本",掩码是八种里罚分(N1+N2+N3+N4)最低的那种,两者都由算法确定、不含随机成分。因为编码器是同一份纯函数、不依赖浏览器专有 API,所以同一输入在任何环境都得到同一张矩阵;单测里也用独立重算的方式复核了掩码选择与罚分最小性。四条罚分分别是 N1 同色连子≥5、N2 2×2 同色块、N3 形如 1011101 的两端浅色组合、N4 深色占比偏离 50% 的程度。
这个页面能扫二维码吗?我的内容会被上传吗?
不能扫码,也绝不会上传。本页只做生成这一半:没有摄像头、没有 WebRTC、没有 fetch/XHR/sendBeacon,你输入的内容只在本地编码、本地下载。至于超出 V40 容量的超长文本、以及 ECI/Kanji/结构化附录这些未实现的能力,页面会如实拒绝或标注不支持,而不是给出一张看似正确实则越界的码。
从内容到一张矩阵,中间要过哪些步骤?
选定版本后,载荷被编成位流,补最多 4 位终止符、对齐到字节边界、再用 0xEC/0x11 交替填满数据码字;Reed–Solomon 在 GF(2^8) 上做,本原多项式 0x11D(注意不是 AES 的 0x11B),生成多项式按 ∏(x−αⁱ) 现推,分块数与每块 EC 码字数取自 ISO 的公开表,数据块按短/长切分(短块长度 = ⌊数据码字÷块数⌋,余下的字节摊给末尾若干长块),最后把各块数据码字按列交织、再把各块 EC 码字按列交织接在后面。
定位图形、格式位这些是谁摆的?
整张矩阵的构造严格走标准:三个角放定位图形与分隔符、第 6 行第 6 列铺计时图形、V≥2 依公式排校正图形(且跳过贴着三个定位角的交汇处)、固定暗模块、格式信息用 BCH(15,5) 生成多项式 0x537 加异或掩码 0x5412 生成并写进两副本、V≥7 再补 18 位版本信息(BCH(18,6) 生成 0x1F25)。页面会把选中的版本号、边长、纠错等级、掩码号、模式、码字构成、格式位十六进制与罚分一并读出来。
对应功能编号 #76无需安装,手机端同样可用按 Ctrl + K 换工具