一句话版本
把一个整数换成它的余数再计算,结果和"先算再取余数"一样。这件事成立,是因为取模映射 π:Z→Z/nZ 是环同态。
弃九法、条形码、银行卡号、身份证最后一位、IBAN,原理都一样:给数据加一个"指纹",抄错一位时指纹大概率会变。凡是差值落在同态的核 nZ 里的错误,指纹都不会变,所以查不出来。
全文分三层:
- 通俗理解:弃九法、弃十一法,以及它们能查和不能查的错误
- 实际用处:ISBN、EAN/UPC 条形码、银行卡 Luhn、身份证、IBAN,最后简单延伸到 CRC 和 Verhoeff
- 数学原理:Z/nZ、环同态、核,以及为什么"模素数"能查得更全,每种方法都配手算例子
关于例子里的号码
文中所有书号、卡号、证件号、账号都是公开的测试号、标准文档里的示例号,或者虚构的号码,不对应任何真实的个人。所有算例都用 Python 验算过。
第一层:通俗理解
1.1 弃九法:用"数字和"检查算术
小学算 3847×526,得出 2023522,怎么快速检查对不对?
弃九法这样做:
- 每个数的各位数字加起来,一直加到只剩一位(也可以中途随时扔掉 9,"弃九"就是这个意思):
- 3847:3+8+4+7=22,2+2=4
- 526:5+2+6=13,1+3=4
- 对这两个"代表数"做同样的运算:4×4=16,1+6=7
- 算答案的数字和:2023522 是 2+0+2+3+5+2+2=16,1+6=7
- 两边都是 7,通过检查。
加法、减法也一样:
- 3847+526=4373。左边 4+4=8,右边 4+3+7+3=17,1+7=8,一致。
- 3847−526=3321。左边 4−4=0,右边 3+3+2+1=9,弃九后是 0,一致。
为什么数字和能代表一个数? 因为"各位数字之和"和原数除以 9 的余数相同。比如 3847÷9=427 余 4,正好等于数字和 22→4。原因是 10 除以 9 余 1,所以 100,1000,… 除以 9 也都余 1,每一位只按它"本身的大小"贡献余数。第三层会严格说明。
而"余数"有一个好性质:先算再取余,等于先取余再算。所以如果真答案除以 9 余 7,你的答案却余 5,那答案一定错了。
1.2 弃九法能查出什么,查不出什么
检查通过不代表一定对
弃九法只能证明"错了",不能证明"对了"。余数不一致说明一定有错;余数一致只能说明可能对。
能查出来的:大多数单个数字写错。比如把 2023522 写成 2023532,数字和变成 17→8=7,立刻发现。
查不出来的:
| 错误类型 |
例子 |
为什么查不出 |
| 两位数字对调 |
2023522 写成 2203522 |
数字还是那几个,数字和不变 |
| 把 0 写成 9 或反过来 |
2023522 写成 2923522 |
数字和刚好变 9,弃九后一样 |
| 某一位差 9 的整数倍 |
2023522 写成 2032522(多了 9000) |
差值是 9 的倍数 |
| 多写或漏写一个 0 |
2023522 写成 20235220 |
末尾的 0 不改变数字和 |
总结一下:只要错答案和正确答案的差是 9 的倍数,弃九法就看不出来。 第一行"对调"是最常见的手误,它恰好就属于这一类:把相邻两位 a,b 对调,差值是 9×(a−b)×10k。
1.3 弃十一法:用"交错和"补漏
换成除以 11 的余数可以弥补对调的问题。因为 10 除以 11 余 −1(也就是余 10),所以
一个数除以 11 的余数 = 从个位开始,一加一减的交错和
例如:
- 3847:7−4+8−3=8
- 526:6−2+5=9
- 8×9=72,72 除以 11 余 6
- 2023522:2−2+5−3+2−0+2=6,一致 ✓
再看刚才弃九法漏掉的两个错误:
- 对调错误 2203522:交错和 2−2+5−3+0−2+2=2=6,查出来了
- 多 9000 的错误 2032522:除以 11 余 8=6,也查出来了
但弃十一法也有盲区:差值是 11 的倍数的错误它查不出来,比如隔一位的两个数字对调(两位同号,交错和不变)。所以实际中常常两个一起用。差值必须同时是 9 和 11 的倍数,也就是 99 的倍数,错误才会同时漏掉两个检查。
1.4 从"检查算术"到"检查号码"
校验位把这个想法反过来用。弃九法检查的是"计算结果",校验位检查的是"抄写或输入的号码":
- 规定一个"指纹函数",例如"加权求和再除以 11 取余"
- 发号码时多加一位(校验位),让整个号码的指纹等于某个固定值,比如 0
- 有人抄号码或者扫描号码时,重新算一遍指纹。不对,就说明号码错了
人抄写时最常见的两类错误是:
- 单个数字错误:…4⋯→…7…,约占人工输入错误的 60%–80%
- 相邻数字对调:…45⋯→…54…,约占 10%–20%
设计校验位就是要选好"模数"和"权重",让这两类错误全部能查出来。下面每种方案都会看它在这两点上表现如何。
第二层:实际用处
先给一张总表,后面逐个解释:
| 方案 |
模数 |
权重 / 规则 |
单个数字错误 |
相邻对调 |
| 弃九法 |
9 |
全是 1 |
漏 0↔9 |
全漏 |
| ISBN-10 |
11 |
10,9,…,1 |
全查出 |
全查出 |
| ISBN-13 / EAN / UPC |
10 |
1,3 交替 |
全查出 |
漏差为 5 的对(如 16↔61) |
| Luhn(银行卡) |
10 |
隔位"加倍后取数字和" |
全查出 |
只漏 09↔90 |
| 身份证 ISO 7064 MOD 11-2 |
11 |
2kmod11 |
全查出 |
全查出 |
| IBAN ISO 7064 MOD 97-10 |
97 |
10kmod97 |
全查出 |
全查出 |
| Verhoeff |
二面体群 D5 |
置换 |
全查出 |
全查出 |
规律很明显:模数是素数(11、97)的方案效果最好。第三层会解释原因。
2.1 ISBN-10:模 11,校验位可以是 X
2007 年以前的书号有 10 位 a1a2⋯a10,规则是
10a1+9a2+8a3+⋯+2a9+1⋅a10≡0(mod11).
因为模 11 的余数有 0 到 10 共 11 种,校验位 a10 有时需要等于 10,这时用罗马数字 X 表示。所以有些老书的书号以 X 结尾。
例子:ISBN 0-306-40615-2(维基百科等资料常用的示例书号)
| 位 |
0 |
3 |
0 |
6 |
4 |
0 |
6 |
1 |
5 |
2 |
| 权重 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
| 乘积 |
0 |
27 |
0 |
42 |
24 |
0 |
24 |
3 |
10 |
2 |
总和 =132=12×11≡0(mod11) ✓
带 X 的例子:0-8044-2957-X。前 9 位的加权和是 0+72+0+28+24+10+36+15+14=199,而 199≡1(mod11)。校验位 c 要满足 1+c≡0,所以 c=10,写成 X。
查错能力:所有单个数字错误、所有对调(不只是相邻对调)都能查出来。
- 把第 8 位的 1 写成 7:总和变为 132+3×6=150≡7≡0,查出
- 把
40615 写成 46015(0 和 6 对调):总和 ≡6≡0,查出
2.2 ISBN-13、EAN-13、UPC:模 10,权重 1 和 3
超市条形码和现在的书号用的是这一套。规则是从左往右,权重 1,3,1,3,… 交替:
a1+3a2+a3+3a4+⋯+a13≡0(mod10).
(12 位的 UPC-A 从左起权重是 3,1,3,1,…,原理相同。)
例子:ISBN-13 978-0-306-40615-7
| 位 |
9 |
7 |
8 |
0 |
3 |
0 |
6 |
4 |
0 |
6 |
1 |
5 |
7 |
| 权重 |
1 |
3 |
1 |
3 |
1 |
3 |
1 |
3 |
1 |
3 |
1 |
3 |
1 |
| 乘积 |
9 |
21 |
8 |
0 |
3 |
0 |
6 |
12 |
0 |
18 |
1 |
15 |
7 |
总和 =100≡0(mod10) ✓。UPC 示例 036000291452 用同样方法验算也通过。
查错能力:
- 单个数字错误:全部查出,因为乘 1 或乘 3 都不会把非零的差变成 10 的倍数。
- 相邻对调:a,b 对调后,总和变化 ±2(a−b)。当 ∣a−b∣=5 时,变化量是 ±10≡0,查不出来。
- 例子:把
40615 写成 40165(6 和 1 对调),得到 978-0-306-40165-7,校验照样通过。
- 漏掉的 5 对是 0↔5、1↔6、2↔7、3↔8、4↔9。
为了兼容条形码系统,ISBN-13 放弃了 ISBN-10 的模 11,所以查错能力反而变弱了。
2.3 银行卡号:Luhn 算法
Visa、Mastercard、银联等卡号的最后一位都是 Luhn 校验位(IBM 的 Hans Peter Luhn 1954 年提出)。规则是:
- 从右往左数,第 2,4,6,… 位乘以 2
- 如果乘出来是两位数,就把两位数字加起来(等价于减 9),例如 7×2=14→1+4=5
- 把所有位加起来,总和必须 ≡0(mod10)
例子:4111 1111 1111 1111(Visa 公开的测试卡号,常用于支付开发测试,不是真卡)
从右往左,偶数位(从左数的第 1,3,5,…,15 位)要加倍:
- 最左的 4 在加倍位:4→8
- 其他 7 个加倍位都是 1:1→2,共 7×2=14
- 8 个不加倍的 1:共 8
总和 =8+14+8=30≡0(mod10) ✓
如果手误把倒数第二位写成 2(...1121),这一位在加倍位,变成 4。总和变为 32≡0,查出。
查错能力:
- 单个数字错误:全部查出,因为"加倍并取数字和"把 0,1,…,9 一一映射到 0,2,4,6,8,1,3,5,7,9,是一个置换
- 相邻对调:只漏一种,09↔90。例如虚构的号码
4090 0000 0000 0003 和 4900 0000 0000 0003 都能通过 Luhn 校验
- 为什么只漏这一对,见第三层 3.6
Luhn 不是安全措施
校验位只防手误,不防伪造。算法是公开的,任何人都能算出合法的校验位,所以真正的安全性靠卡组织的数据库、CVV 和 3-D Secure。
2.4 中国居民身份证第 18 位:ISO 7064 MOD 11-2
18 位身份证号 a1a2⋯a18 中,前 6 位是地区码,接下来 8 位是出生日期,再 3 位是顺序码,最后 a18 是校验码。规则是
i=1∑18ai⋅218−i≡1(mod11),
其中 a18 如果需要等于 10,就写成 X。这就是为什么有些人的身份证号以 X 结尾,原因和 ISBN-10 完全一样。
把 218−i 对 11 取余,前 17 位的权重是
7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,
最后一位的权重是 20=1。实际计算时先求前 17 位的加权和 S,再查表:
| Smod11 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
| 校验码 |
1 |
0 |
X |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
(这张表就是解方程 S+c≡1(mod11) 得到的结果。)
例子:11010519491231002X。这是国家标准 GB 11643—1999 里的示例号码,不对应真实个人。
| 位 |
1 |
1 |
0 |
1 |
0 |
5 |
1 |
9 |
4 |
9 |
1 |
2 |
3 |
1 |
0 |
0 |
2 |
| 权重 |
7 |
9 |
10 |
5 |
8 |
4 |
2 |
1 |
6 |
3 |
7 |
9 |
10 |
5 |
8 |
4 |
2 |
| 乘积 |
7 |
9 |
0 |
5 |
0 |
20 |
2 |
9 |
24 |
27 |
7 |
18 |
30 |
5 |
0 |
0 |
4 |
S=167=15×11+2,所以 S≡2,查表得校验码 X ✓。验证:167+10=177=16×11+1≡1 ✓。
如果把生日 1231 抄成 1213(相邻的 3,1 对调),算出的校验码会变成 9,与 X 不符,查出。
查错能力:所有单个数字错误和所有相邻对调都能查出来。
2.5 IBAN:模 97
国际银行账号(IBAN,欧洲、中东等地使用)用两位校验数字,规则是 ISO 7064 MOD 97-10:
- 把开头 4 个字符(国家代码和两位校验数字)挪到末尾
- 字母换成两位数:A=10, B=11, …, Z=35
- 得到的大整数必须 ≡1(mod97)
例子:GB82 WEST 1234 5698 7654 32。这是 IBAN 标准文档常用的虚构示例账号。
- 挪动:
WEST12345698765432GB82
- 换字母(W=32, E=14, S=28, T=29, G=16, B=11):
N=3214282912345698765432161182
- 手算 Nmod97 时可以分段:先取一段,求余,再把余数接到后面的数字前面,继续求余:
3214282917023456982976543212461182≡70(mod97)≡29(mod97)≡24(mod97)≡1(mod97) ✓
这种分段算法成立,也是因为取模是环同态,第三层会说明。
生成校验位时,先把校验位当成 00 算出 N0,校验位就是 98−(N0mod97)。这个例子里算出来正好是 82。
为什么选 97:97 是小于 100 的最大素数。两位校验数字最多能表示 100 种值,97 几乎全用上了,而且它是素数,查错能力最强。IBAN 能查出所有单字符错误和所有相邻数字对调,实际漏检率约为 1/97≈1%。
2.6 延伸:CRC 和 Verhoeff
CRC(循环冗余校验):把"模一个数"换成"模一个多项式"
以太网帧、ZIP 压缩包、PNG 图片都用 CRC。它把比特串 bm−1⋯b1b0 看成 F2[x] 里的多项式 ∑bixi(F2=Z/2Z),然后对一个固定的生成多项式 g(x) 取余:
F2[x] ⟶ F2[x]/(g(x)).
这也是一个环同态,核是理想 (g)。只要错误多项式 e(x) 不被 g(x) 整除,错误就能查出来。选好 g(比如 CRC-32 的那个 32 次多项式)可以保证查出所有长度 ≤32 的连续错误(突发错误)。这和弃九法是同一个模式,只是把 Z 换成了 F2[x]。
Verhoeff 算法:用非交换群 D5 一次解决两类错误
前面的方案都在交换环 Z/nZ 里做加权求和。只要模数是 10,就总会漏掉一些错误:EAN 漏 5 对,Luhn 漏 1 对。可以证明,在 Z/10Z 里用"加权和"不可能同时查出所有单个错误和所有相邻对调。
Jacobus Verhoeff 1969 年的做法是:把 10 个数字对应到二面体群 D5(正五边形的 10 个对称:5 个旋转加 5 个翻转)的 10 个元素,再配一个精心设计的置换 σ。规则是
σ1(a1)∗σ2(a2)∗⋯∗σn(an)=e,
其中 ∗ 是 D5 里的乘法(不交换)。因为 xy=yx,对调相邻两位一般会改变乘积,于是只用一位十进制校验位就做到了单个错误和相邻对调全部查出。
例子:数字串 236 的 Verhoeff 校验位是 3,2363 通过检查,而把它改成 2633 就不能通过。印度的 Aadhaar 身份号码用的就是这个算法。
第三层:数学原理
3.1 同余与 Z/nZ
固定正整数 n。如果 n∣a−b,就说 a≡b(modn)。这是一个等价关系,a 的等价类记为
aˉ=a+nZ={…,a−n, a, a+n, …}.
全部等价类构成 Z/nZ={0ˉ,1ˉ,…,n−1},运算定义为
aˉ+bˉ=a+b,aˉbˉ=ab.
良定义
要说明上面的运算不依赖代表元的选取:若 a≡a′、b≡b′,则
ab−a′b′=a(b−b′)+b′(a−a′)∈nZ,
因为 nZ 是理想:它对加法封闭,并且吸收乘法(r⋅nZ⊆nZ)。这正是商环 R/I 能定义乘法的原因。
3.2 取模映射是环同态
定义
π:Z→Z/nZ,π(a)=aˉ.
由 3.1 的运算定义直接可得
π(a+b)=π(a)+π(b),π(ab)=π(a)π(b),π(1)=1ˉ,
所以 π 是一个(满的)环同态。用文字说就是"先算再取余 = 先取余再算",也就是
ab=aˉbˉ.
弃九法就是取 n=9 的情形:要检查 c=?ab,只需检查 cˉ=?aˉbˉ 在 Z/9Z 里是否成立。Z/9Z 只有 9 个元素,计算量很小。
逻辑方向要注意:
c=ab ⟹ π(c)=π(a)π(b),
但反过来不成立。所以弃九法只能否定,不能肯定。
1.1 的例子用同态语言重写
π(3847)=4ˉ,π(526)=4ˉ,4ˉ⋅4ˉ=16=7ˉ,π(2023522)=7ˉ。两边相等,同态没有否定这个等式。
IBAN 的分段求余也是同态性质的应用。设 N=A⋅10k+B,那么
π(N)=π(A)π(10)k+π(B),
所以可以先把 A 换成它的余数 r,再算 r⋅10k+B 的余数,结果不变。
3.3 为什么"10≡1"推出数字和
设 N=∑k=0mdk10k,其中 dk∈{0,…,9} 是各位数字。用同态 π:Z→Z/9Z,
π(N)=k=0∑mπ(dk)π(10)k=k=0∑mdˉk⋅1ˉk=∑kdk,
因为 10=9+1,所以 π(10)=1ˉ。也就是说,
N≡d0+d1+⋯+dm(mod9).
模 3 同理,因为 10≡1(mod3)。这就是"数字和被 3 整除则原数被 3 整除"的原因。
换成模 11:10=11−1,所以 π(10)=−1,于是
N≡k=0∑m(−1)kdk=d0−d1+d2−⋯(mod11),
这就是交错和。
手算
N=2023522,其中 d0=2,d1=2,d2=5,d3=3,d4=2,d5=0,d6=2:
k∑dk=16≡7(mod9),k∑(−1)kdk=2−2+5−3+2−0+2=6(mod11).
实际上 2023522=224835×9+7=183956×11+6 ✓
3.4 核是 9Z:哪些错误查不出
kerπ={a∈Z: π(a)=0ˉ}=9Z.
设正确答案是 c,写下的答案是 c′,错误量为 e=c′−c。那么
π(c′)=π(c)⟺π(e)=0ˉ⟺e∈kerπ=9Z.
所以一个错误查不出来,当且仅当错误量落在核里。这是同态最基本的性质:π(x)=π(y)⟺x−y∈kerπ。由第一同构定理,Z/kerπ≅Z/9Z,核里的差别在像里完全看不出来。
逐一对照 1.2 的表格:
- 单个数字错误:第 k 位从 a 变成 b,错误量 e=(b−a)10k。因为 gcd(10,9)=1,所以 e∈9Z⟺9∣b−a⟺{a,b}={0,9}。
- 相邻对调:第 k+1 位和第 k 位分别是 a,b,对调后错误量为
e=(b−a)10k+1+(a−b)10k=9(b−a)10k∈9Z,
所以永远查不出来。
- 模 11:同一个相邻对调,e=9(b−a)10k≡9(b−a)(−1)k(mod11)。因为 11 是素数,9≡0,而 0<∣b−a∣≤9 时 b−a≡0,所以 e≡0,一定查得出。
- 隔一位对调:e=(b−a)(10k+2−10k)=99(b−a)10k,同时属于 9Z 和 11Z,两种方法都查不出。
3.5 加权校验位的一般框架,以及素数为什么重要
所有"加权和"型校验位都可以写成
φ(a1,…,am)=i=1∑mwiai ∈ Z/nZ,合法号码⟺φ=tˉ.
φ 是从 (Z/nZ)m 到 Z/nZ 的模同态(线性映射),所以查错分析和 3.4 一样:错误向量 e 查不出来,当且仅当 e∈kerφ。
(1) 单个数字错误:第 i 位从 a 变成 b,φ 的变化量是 wi(b−a)。
(2) 第 i,j 位对调:设原来分别是 a,b,变化量是
wi(b−a)+wj(a−b)=(wi−wj)(b−a).
因为数字满足 0≤a,b≤9,所以 a=b 时 b−a∈{±1,…,±9}。
定理(模素数时的查错能力)
设 n=p 是素数且 p>9(例如 11 或 97)。
- 若所有权重 wi≡0(modp),则所有单个数字错误都能查出。
- 若 wi≡wj(modp),则第 i,j 位的对调都能查出。
证明:p 是素数,所以 Z/pZ 是域,没有零因子:xy=0⇒x=0 或 y=0。
由于 p>9,0<∣b−a∣≤9<p,所以 b−a=0ˉ,即 b−a 可逆。
- (1) wi 和 b−a 都可逆,乘积 wi(b−a)=0ˉ。
- (2) wi−wj 和 b−a 都可逆,乘积 (wi−wj)(b−a)=0ˉ。■
逐一检查:
- ISBN-10(p=11,wi=11−i):wi∈{1,…,10} 全部非零;对任意 i=j,wi−wj=j−i∈{±1,…,±9} 也非零。所以单个错误和任意位置的对调都能查出。校验位如果是 10,就必须写成 X,这是用素数 11 而不是 10 付出的代价。
- 身份证 MOD 11-2(p=11,wi=218−i):2 在 Z/11Z 中可逆,所以每个 wi=0。相邻两位的权重差是
wi−wi+1=2k+1−2k=2k=0ˉ,
所以相邻对调都能查出。另外,2 是模 11 的原根,21,…,210 恰好取遍 {1ˉ,…,10},因此任意两位只要相距不是 10 的倍数,权重就不同,对调也能查出。
- IBAN MOD 97-10(p=97,按十进制数字看,w=10k):10k 可逆;相邻差 10k+1−10k=9⋅10k 可逆。10 在 Z/97Z 中的阶是 96,所以权重在很长一段内互不相同。
反例:模数不是素数时,零因子会造成漏检
- EAN(n=10,权重 1,3):
- 单个错误:w∈{1,3},在 Z/10Z 中可逆(gcd(3,10)=1),所以全部能查出。
- 相邻对调:变化量 (3−1)(b−a)=2(b−a)。但 2ˉ 是 Z/10Z 中的零因子:2ˉ⋅5ˉ=0ˉ。所以 b−a=±5 时变化量为 0ˉ,查不出来。这正是 2.2 里
40615 改成 40165 仍能通过的原因:
(3−1)(1−6)=−10≡0(mod10).
- 弃九法(n=9,权重全是 1):相邻对调时 wi−wj=0,任何对调都查不出。
一句话总结
校验位的设计要点,是让权重 wi 和权重差 wi−wj 在 Z/nZ 里都是单位(可逆元)。n 是素数时,Z/nZ 是域,非零元都是单位,这个要求很容易满足。n=10 时有零因子 2 和 5,就总会留下漏洞。
3.6 Luhn 为什么只漏 09↔90
Luhn 不是纯粹的加权和。设"加倍取数字和"函数为
δ(x)={2x,2x−9,0≤x≤4,5≤x≤9,
它的取值表是
| x |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
| δ(x) |
0 |
2 |
4 |
6 |
8 |
1 |
3 |
5 |
7 |
9 |
(注意 δ(x)≡2x(mod9),因为数字和不改变模 9 的余数,这里又用到了 3.3。)
单个错误:如果发生在不加倍的位置,变化量是 b−a≡0(mod10);如果发生在加倍的位置,变化量是 δ(b)−δ(a)。从上表可以看出 δ 是 {0,…,9} 上的置换(单射),所以 a=b 时 δ(a)=δ(b),并且两者都在 0 到 9 之间,差不可能是 10 的倍数。因此单个错误全部能查出。
相邻对调:相邻两位中恰好一位加倍。设原来加倍位是 a、普通位是 b,对调后加倍位是 b、普通位是 a。总和的变化量为
(δ(b)+a)−(δ(a)+b)=f(b)−f(a),f(x):=δ(x)−x.
计算 f(x)mod10:
| x |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
| f(x)=δ(x)−x |
0 |
1 |
2 |
3 |
4 |
−4 |
−3 |
−2 |
−1 |
0 |
| f(x)mod10 |
0 |
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
0 |
在 Z/10Z 中,f 只有一次"撞车":f(0)=f(9)=0。所以 a=b 时,
f(a)≡f(b)(mod10)⟺{a,b}={0,9},
也就是说,Luhn 只漏掉 09↔90 这一种相邻对调。直观上,0 加倍还是 0,9 加倍是 18→9,两者都是 δ 的不动点,所以无论哪一位加倍,总和都一样。
手算:测试卡号 4111 1111 1111 1111
从右往左编号 i=1,…,16,偶数 i 加倍:
i 奇∑ai=8⋅1=8,i 偶∑δ(ai)=δ(4)+7δ(1)=8+14=22,
合计 30≡0(mod10) ✓。
反例(虚构的号码):4090 0000 0000 0003 和 4900 0000 0000 0003 两个都能通过检查,因为 f(0)=f(9)。
3.7 全景图
和抽象代数的对应
| 代数概念 |
在本文里的角色 |
| 环同态 π:Z→Z/nZ |
"先取余再算 = 先算再取余",是弃九法的依据 |
| 核 kerπ=nZ 是理想 |
查不出的错误恰好是错误量落在核里的那些 |
| 商环 Z/nZ 的良定义 |
分段求余、数字和、交错和都能算 |
| Z/pZ 是域(p 素数) |
非零元可逆、无零因子,所以 ISBN-10、身份证、IBAN 能全部查出 |
| 零因子(2ˉ⋅5ˉ=0ˉ) |
EAN 漏掉差为 5 的对调 |
| 多项式环商 F2[x]/(g) |
CRC |
| 非交换群 D5 |
Verhoeff 校验 |