什么是luhn算法?

IT 技术 19 阅读 更新于 2026-09-25 17:36

Luhn算法(卢恩算法,也叫模10算法)

Luhn 是一种简单的校验算法,用来验证一串数字(银行卡号、身份证、IMEI、会员号等)是否格式合法,不能验证信息真假,只能检测输入错误(比如输错一位、相邻数字颠倒)。

由 IBM 工程师 Hans Peter Luhn 发明。

✅ 计算步骤

举个例子:卡号 49927398716(最后一位6是校验位)

规则:从右往左,从倒数第二位开始,隔一位乘以2

  1. 把数字从右向左编号:

4 9 9 2 7 3 9 8 7 1 | 6
从右数:第1位=6(校验位不动),第2位=1,第3位=7,第4位=8……

  1. 偶数位置(从右数第2、4、6…位)数字 ×2

如果乘完结果≥10,把十位和个位相加(等价于减9)

  • 1×2 = 2
  • 7×2 =14 → 1+4=5
  • 8×2 =16 →1+6=7
  • 3×2 =6
  • 2×2 =4
  • 9×2 =18 →1+8=9
  1. 奇数位置(除校验位外)数字保持原样:9、7、9、4
  1. 把上面所有结果相加,再加上最后的校验位:

总和如果 是10的倍数 → Luhn校验通过

校验公式:总和 mod 10 == 0

📌 快速总结

  1. 从最右边开始,跳过最后一位校验码;
  2. 向左依次,隔一个数字 ×2;
  3. 乘2后大于9,各位相加;
  4. 全部数字求和;
  5. 总和对10取余等于0,校验成功。

🎯 能检测什么,不能检测什么

✅ 可以发现:

  • 单个数字输错(如 123 → 124)
  • 相邻两位数字交换(12→21,大部分情况)

❌ 无法发现:

  • 两个数字同时错,且错误刚好抵消校验和
  • 完全编造但符合Luhn规则的号码(只能校验格式,不能验证号码真实存在)

Python 简易实现

def luhn_check(num_str):
    total = 0
    # 反向遍历
    for i, c in enumerate(reversed(num_str)):
        digit = int(c)
        if i % 2 == 1: # 倒数第2、4...位 ×2
            digit *= 2
            if digit > 9:
                digit -=9
        total += digit
    return total %10 ==0

print(luhn_check("49927398716")) # True

常见用途

银行卡号、信用卡号、IMEI手机序列号、加拿大社保号、部分平台编号校验。

如果你想要,我可以给你 JS / Java / C 版本的 Luhn 代码。

产品的防伪二维码建议用哪些算法生成?

防伪二维码配套校验算法选型说明

重点:二维码本身只是载体(存文本),二维码标准没有内置防伪算法。防伪能力来自二维码里面存储的数据 + 后台校验逻辑,二维码只是把这段信息展示给手机扫码端。
区分两个概念:

  1. 二维码编码:QR Code / Data Matrix 等,只是图形编码,不防伪;
  2. 防伪校验算法:用来生成防伪码、校验真伪、防篡改。

一、轻量场景:单品短码、本地校验(不需要联网也能初步校验)

1. Luhn 算法(你刚才问的)

✅ 优点:计算极快、数字串、人眼可打印,适合短序列号,检测录入错误;
❌ 缺点:安全强度很低,只能防手输错误,不能防伪造。攻击者很容易批量生成符合Luhn的号码。
👉 适用:辅助校验(防扫码输入错误),绝对不能单独作为防伪核心。

2. Mod 校验、加权和校验(类似Luhn变种)

和Luhn定位一致,仅做格式校验,不防破解。

小结:这类校验和类算法只能做格式合法性检查,不能防伪,只适合搭配主防伪算法一起用。

二、主流商用防伪方案(推荐)

方案A:带签名的防伪码(推荐,强防伪)

核心:非对称加密算法(RSA / ECC(SM2国密))
流程:

  1. 服务器(私钥)生成唯一流水号,对流水号做签名,把【流水号+签名】放到二维码;
  2. 手机扫码拿到内容,使用公钥验证签名;
  3. 一旦二维码里的内容被篡改,签名校验直接失败。
  • SM2(国密):国内产品首选,合规,椭圆曲线,签名短,适合二维码存储空间有限场景;
  • RSA:成熟,但是签名结果更长,二维码内容会变多;

✅ 优势:无法伪造有效签名,不需要把密钥暴露在包装/客户端;
✅ 搭配:二维码内容可以再加 SM3(国密哈希)辅助;
❌ 必须联网校验(或者内置公钥离线验签)。

方案B:哈希摘要方案(SM3 / SHA256)

适合:码体存储短摘要,原始数据在后台数据库

流程:

  1. 生成唯一序列号,后台计算 SM3(序列号+密钥盐);
  2. 二维码存放:序列号+哈希摘要;
  3. 扫码后上传序列号,后台重新计算哈希比对。

✅ SM3国密,国内政企、品牌产品推荐;SHA256通用;
⚠️ 注意:哈希算法不能直接裸用!必须加盐(salt)。不加盐很容易彩虹表批量碰撞伪造。

缺点:纯哈希方案必须联网到服务器校验,不能离线校验;如果盐泄露,批量伪造风险上升。

方案C:一次性验证码(OTP类,较少用于包装防伪)

HMAC-SHA256,适合动态码,包装印刷静态防伪码一般不用。

三、工程组合推荐(实际项目常用组合)

✅ 推荐1(国内品牌产品首选,国密方案)

二维码存储内容:序列号 + SM2签名

  • 防伪核心:SM2非对称签名(防篡改、防伪造)
  • 可选附加:SM3做内部摘要,Luhn做前端格式校验(仅防输入错误)

适用:烟酒、化妆品、汽配、食品等实体商品防伪溯源。

✅ 推荐2(海外产品,无国密要求)

二维码:序列号 + ECDSA(secp256r1)签名
或者:序列号 + SHA256加盐哈希,联网校验。

四、避坑提醒(非常关键)

  1. ❌ 不要单独用 Luhn / CRC / 简单加权和做防伪!

CRC32、Luhn这类校验算法,攻击者可以批量生成大量合法号码,完全没有防伪能力,只能用来校验用户手动输错数字。

  1. ❌ 不要把密钥直接写在二维码里。
  2. ❌ 只靠二维码图片本身不能防伪,二维码图片可以拍照复制。

二维码防伪本质是:一物一码 + 后台数据库/数字签名校验;如果别人拍照复制二维码,多人扫码,后台可以标记“已被多次查询,疑似假冒”。

五、补充:二维码本身选型(载体)

防伪常用二维码类型:

  • QR Code:最通用,手机微信/支付宝直接扫;
  • Data Matrix:小尺寸,小标签(零件、药瓶)常用,容错强。

如果你告诉我场景:产品行业、是否要求国密、是否支持扫码联网、一个码最多允许多少字符,我可以直接给你一套完整的数据结构示例(二维码里面字符串格式)。

← 返回IT 技术 yicool 百科 · 什么是luhn算法?

评论 0