← 返回博客

个人博客

纯系统全家福:从 MOD 11-2 到 MOD 1271-36(GB/T 17710 续一)

上一篇(GB/T 17710 解读)把校验字符的来龙去脉讲清楚了,并手算了一遍最常用的 MOD 11-2 和 MOD 97-10。这一篇,我们把 GB/T 17710 里的"纯系统"一次讲完——它们都只有一个校验字符(或两位),公式却高度统一,看懂一个就看懂一片。

一、纯系统的统一公式

所有纯系统玩的都是同一件事:给数据算一个加权和,再对模数 M 取模,让"数据 + 校验字符"整串满足一个固定关系。

设数据为 a₁ a₂ … aₙ(从左到右),从最右一位起,权重依次是 r⁰, r¹, r², …(r 是基数)。加权和:

S = Σ aᵢ · r^(i-1)   (i 从最右一位数起)

校验字符 C 让"完整串"满足:

S_full ≡ 1 (mod M)

M 是模数,r 是基数,字符集和校验位数各系统不同。GB/T 17710 给出的纯系统有五个:

  • MOD 11-2:M=11, r=2,数字 0-9(10 用 X 表示),1 位校验
  • MOD 37-2:M=37, r=2,0-9、A-Z 加 *,1 位校验
  • MOD 97-10:M=97, r=10,数字,2 位校验
  • MOD 661-26:M=661, r=26,纯字母 A-Z,2 位校验
  • MOD 1271-36:M=1271, r=36,0-9、A-Z,2 位校验
flowchart LR A["纯系统 单类校验字符"] --> B["数字 MOD 11-2"] A --> C["字母数字 MOD 37-2"] A --> D["数字 双位 MOD 97-10"] A --> E["字母 双位 MOD 661-26"] A --> F["字母数字 双位 MOD 1271-36"]

二、MOD 11-2 回顾(详见上篇)

数据 "1234567",从右起权重 1, 2, 4, 8, 5, 10, 9,数据加权和是 153。把校验字符 C 接在最右边(权重最低,为 1),整串加权和要求 ≡ 1 (mod 11):

加权和 = C×1 + 7×2 + 6×4 + 5×8 + 4×5 + 3×10 + 2×9 + 1×7 = C + 153
153 mod 11 = 10,所以 C + 10 ≡ 1 → C = 2

完整串为 "12345672",代入验证加权和 = 155,155 mod 11 = 1,通过。

三、MOD 37-2:能装字母数字的版本

MOD 11-2 只能吃数字。MOD 37-2 把字符集扩到 **0-9、A-Z、再加 ***(共 37 个,正好模 37),仍然只挂 1 位校验字符。字母的取值规则:数字就是它本身,A=10、B=11、…、Z=35,*=36。

手算一遍,取数据 "7K9":

字符(右→左):    9    K    7
字符取值:         9   20    7
权重(2^n mod 37):  1    2    4
乘积:             9   40   28

加权和 N = 9 + 40 + 28 = 77。校验字符 C 满足 (1 − 2×77) mod 37:

2×77 = 154,154 mod 37 = 6
C = (1 − 6) mod 37 = 32
32 在字母区:32 − 10 = 22 → 第 22 个字母 = W

所以校验字符是 W,完整串 "7K9W"。代入整串按同样框架重算,加权和 mod 37 = 1,通过。当你标识里需要混着字母和数字、又只肯多占 1 位时,它就是 MOD 11-2 的替身。

四、MOD 97-10 回顾(详见上篇)

IBAN(国际银行账号)用的就是它。模数 97、基数 10,挂 2 位校验。公式:把数据当十进制整数 N,两位校验码 C 满足 (100×N + C) mod 97 = 1,即 C = (1 − 3N) mod 97(结果两位补零)。

数据 "123456" → C = 76,完整串 "12345676",12345676 mod 97 = 1,通过。两位校验比一位多扛了一截错误,所以金融账号偏爱它。

五、MOD 661-26:纯字母的双校验

前面都是"数字或字母数字"。MOD 661-26 反过来,只认纯字母 A-Z(26 个,模 661,基数 26),挂 2 位字母校验。手算一遍,取数据 "XKCD"(字母取值 X=23, K=10, C=2, D=3):

字符(右→左):    D    C     K     X
字符取值:         3    2    10    23
权重(26^n):       1   26   676  17576
乘积:             3   52  6760 404248

加权和 N = 3 + 52 + 6760 + 404248 = 411063。两位校验由 (1 − 26²×N) mod 661 算得,再按 26 进制拆成两个字母:高位 20、低位 5 → U(20)+ F(5)。

所以校验字符是 UF,完整串 "XKCDUF",代入验证加权和 ≡ 1 (mod 661),通过。纯字母场景(比如某些内部代号、序列号)用它最干净——校验位也是字母,整串看着统一。

六、MOD 1271-36:字母数字的双校验

MOD 1271-36 是 MOD 37-2 的"双位加强版":字符集 0-9、A-Z(36 个,模 1271,基数 36),挂 2 位校验。手算一遍,取数据 "B4D"(取值 B=11, 4=4, D=13):

字符(右→左):    D    4    B
字符取值:        13    4   11
权重(36^n):       1   36  1296
乘积:            13  144 14256

加权和 N = 13 + 144 + 14256 = 14413。两位校验由 (1 − 36²×N) mod 1271 算得,按 36 进制拆成两个字符:高位 17、低位 28 → H(17)+ S(28)。

所以校验字符是 HS,完整串 "B4DHS",代入验证加权和 ≡ 1 (mod 1271),通过。字母数字都要、还想多扛点错误时,它是 MOD 37-2 的升级选择。

七、怎么选

  • 只用数字、1 位够 → MOD 11-2
  • 数字 + 字母、1 位 → MOD 37-2
  • 只用数字、要更强 → MOD 97-10(2 位)
  • 纯字母、要 2 位 → MOD 661-26
  • 数字 + 字母、要 2 位 → MOD 1271-36

一句话记住:纯系统 = 一个模数 + 一个基数 + 加权和取模,校验字符数量由模数大小决定(模不大就 1 位,模大能 2 位)。NDI 标识码落在"1 位校验字符"这一类,用的就是纯系统思路。

下一篇讲"混合系统"——它用两个模数做"乘积折叠",让校验字符永远留在原生字符集里(数字就还是数字,字母就还是字母,绝不冒出 X 这种补字符)。