生活工具 · 证件号码

银行卡校验

Luhn 算法 + 发卡行识别(本地 BIN 库)

本地处理 · 不上传 免费 · 无需登录 无次数限制 累计 69 次使用
本地 Luhn 校验 + BIN 识别 · 不联网 · 不存储
点击卡面 / 翻转卡面 查看磁条背面 · 仅示意,不显示 CVV
等待输入 Luhn mod-10 checksum
银行卡号0 位
LUHN 校验mod-10 checksum · ISO/IEC 7812-1

卡组织识别 card scheme by leading digits

本地 BIN / IIN 库 local issuer table · click to fill

BIN(Bank Identification Number,发卡行识别码)= 卡号前 6–8 位,用于定位发卡机构与卡组织。 本工具内置中国主流银行(工/建/农/中/招/交/邮储/中信/民生/光大/浦发/兴业等)借记 + 信用卡常见 BIN 段, 以及国际卡组织规则。匹配按「最长前缀优先」,未命中时仍按首位规则给出卡组织与可能类型。

隐私声明|本工具完全在浏览器本地运行,输入的卡号 不会发送到任何服务器,也不存储。 本工具仅做格式校验(Luhn)与 BIN 识别并非真伪验证——Luhn 通过只代表卡号格式自洽, 不代表卡片已发行、未挂失或有余额。仍强烈不建议在任何在线工具输入完整真实卡号;分享链接默认不携带完整卡号
就绪 · 输入卡号即可本地校验与识别
第一节

关于本工具

About

收银台前输完卡号,按下确认键前的那几秒——卡号格式对不对、是哪家银行发卡,心里没底。这个工具在浏览器里用 Luhn 算法当场校验卡号合法性,再匹配本地 BIN 库识别发卡行和卡种。校验全程在本地完成,卡号不上传任何服务器,适合支付前自检、财务对账时快速验证卡号有效性。

使用场景

电商结算对账

财务小陈每月初要核对上千笔银行流水,发现一笔 3 月 12 日的交易号尾号是 6,而系统记录是 8。她不确定是输入手误,还是卡号本身无效。用本工具校验该卡号,Luhn 算法直接判定为无效卡号,说明是录入错误,省去联系银行查证的半天时间。

销售录入客户卡号

房产中介老张在签约现场录入客户信用卡号,客户报了一串数字后,老张担心听错一位导致扣款失败。他当场用本工具校验,发现最后一位校验码不匹配,让客户重新报了一遍,原来是「6」和「9」听混了。修正后校验通过,当场完成定金支付。

开发联调支付接口

后端程序员小李在对接三方支付时,需要生成一批测试卡号用于沙箱环境。他手动编了几组 16 位数字,但调用接口一直报「卡号格式错误」。用本工具一测,发现其中两个卡号 Luhn 校验失败,原来是最后一位随便填的。修正后接口调用成功,调试时间从 2 小时缩到 10 分钟。

银行柜台快速验证

柜员小赵遇到一位客户要绑定他行借记卡,但客户只带了卡,记不住开户行。小赵输入卡号前 6 位,本工具本地 BIN 库立即匹配出发卡行是「招商银行」、卡种是「储蓄卡」。不用等跨行查询系统响应,当场完成绑定,客户等待时间从 3 分钟降到 30 秒。

个人理财记账纠错

用户小张在记账 App 手动录入信用卡账单,发现一笔 1 月 5 日的消费卡号比平时少一位。他不确定是 App 截断了,还是自己漏录了。用本工具输入完整卡号,Luhn 校验通过,说明卡号本身有效,只是记账时少写了最后一位。补全后账目与银行流水一致,月底对账不再头疼。

对比矩阵

维度本工具在线校验站手工核对
隐私卡号纯本地计算,不出浏览器卡号需上传至对方服务器卡号全程在手中,无网络传输
速度输入即出结果,无网络延迟依赖网络请求,1-3 秒响应逐位心算或查表,耗时数分钟
发卡行识别内置 BIN 库,离线识别发卡行部分站点需联网查询 BIN 库需自行记忆或翻阅发卡行号段表
离线可用断网环境下完整可用断网后完全不可用完全离线,依赖个人知识
批量处理单次输入一张卡号多数支持单次输入可一次核对多张,但效率极低
第二节

使用指南

Getting Started

使用步骤

  1. 1在输入框粘贴或键入待校验的银行卡号(16-19 位数字),结果区立即显示「通过」或「不通过」
  2. 2通过校验的卡号下方自动展示发卡行名称(如中国银行、工商银行),匹配本地 BIN 库
  3. 3点击结果区「复制」按钮,将校验结果或卡号原文复制到剪贴板
  4. 4若卡号未通过 Luhn 校验,结果区提示「号码格式或校验位错误」,无需重新输入即可修改

输入输出示例

输入输出说明
6222021234567890卡号:6222021234567890 发卡行:中国工商银行 卡种:借记卡 校验结果:有效常规:工商银行借记卡标准19位卡号,验证Luhn算法和BIN库匹配是否正常
6228481234567890卡号:6228481234567890 发卡行:中国农业银行 卡种:借记卡 校验结果:有效常规:农业银行借记卡,覆盖另一家主流银行,确保BIN库覆盖多家
5201521234567890卡号:5201521234567890 发卡行:中国银行 卡种:信用卡 校验结果:有效边界:信用卡卡号(以5开头),验证工具能区分借记卡与信用卡类型
6222021234567891卡号:6222021234567891 发卡行:中国工商银行 校验结果:无效(Luhn校验失败)边界:仅最后一位不同(输错),验证Luhn算法能正确捕获一位数字错误
1234567890123456卡号:1234567890123456 发卡行:未知(BIN库未收录) 校验结果:有效易错:卡号格式正确但BIN不在本地库中,用户可能误以为工具坏了——实际Luhn通过但无发卡行信息
62220212345678卡号:62220212345678 校验结果:无效(卡号长度不足14位)易错:用户输入过短(14位而非16/19位),工具应明确提示长度不合法而非静默处理
6222021234567890123卡号:6222021234567890123 校验结果:无效(卡号长度超过19位)边界:超长输入(20位),验证工具对长度上限的截断或拒绝逻辑

常见错误对照

1.卡号包含空格或连字符

✗ 错误6222 0200 1234 5678
✓ 修复6222020012345678

Luhn 算法逐位运算,空格/连字符会破坏数字序列,导致校验失败。BIN 库也要求纯数字串才能匹配前 6 位。

2.输入非银行卡号(如身份证号、手机号)

✗ 错误110101199001011234
✓ 修复6222020012345678

身份证号虽为 18 位数字,但不符合 Luhn 校验规则(模 10 结果非 0),且前 6 位 BIN 不在发卡行库中,工具会报无效。

3.卡号位数不足或超长

✗ 错误622202
✓ 修复6222020012345678

银行卡号通常 16-19 位。Luhn 算法对任意长度数字都计算,但过短(如 6 位)无法通过校验,且 BIN 识别后无完整卡号意义。

4.误将 CVV 或有效期当作卡号输入

✗ 错误123
✓ 修复6222020012345678

CVV 是 3 位安全码,有效期是 MM/YY 格式,均非卡号。工具仅校验 Luhn 和 BIN,对非卡号数字会返回无效。

5.输入字母或特殊字符

✗ 错误6222ab0012345678
✓ 修复6222020012345678

Luhn 算法只处理数字字符。字母或符号会被工具过滤或直接拒绝,用户应确保输入纯数字。

6.使用已过期或注销的卡号验证

✗ 错误6222020012345678(已注销)
✓ 修复6222020012345678(有效卡)

Luhn 算法和 BIN 库只能验证卡号格式和发卡行,无法查询卡状态。用户误以为工具能判断卡片是否可用。

7.混淆借记卡与信用卡 BIN 范围

✗ 错误假设所有 62 开头都是信用卡
✓ 修复62 开头多为银联借记卡,也有信用卡

BIN 库按发卡行和卡种类分配,同一 BIN 前缀可能对应多种卡类型。工具返回的发卡行信息需结合卡面标识确认。

第三节

工作原理

How It Works

核心公式

Luhn 校验:从右向左,偶数位数字×2(若结果≥10则减9),所有位求和,和 mod 10 = 0 则通过

变量说明

  • 卡号银行卡号,纯数字字符串
  • 偶数位从右数第2、4、6…位(含0)
  • 奇数位从右数第1、3、5…位
  • 校验和所有位处理后的数字之和

示例

卡号 6217002680001234:从右向左,奇数位 4+3+2+0+0+8+0+7+1+2+6=33;偶数位 3×2=6(<10)、1×2=2、0×2=0、0×2=0、6×2=12(≥10→12-9=3)、2×2=4、7×2=14(→5)、6×2=12(→3),偶数位和=6+2+0+0+3+4+5+3=23;总校验和=33+23=56,56 mod 10=6≠0,卡号无效。若末位改为6(即6217002680001236),则奇数位和=33+2=35,偶数位和不变=23,总校验和=58,58 mod 10=8≠0,仍无效。正确校验位应为使总和为10的倍数的数字,本例正确末位为8(奇数位和=33+4=37,偶数位和=23,总和=60,60 mod 10=0)。

输入卡号16-19 位数字Luhn 校验从右向左双倍求和模 10 验证BIN 库匹配前 6 位查表识别发卡行输出结果有效 / 无效发卡行名称
用户输入 本地处理 输出结果
第四节

开发者集成

For Developers

6 种主流语言实现,复制即用:

import re # 本地 BIN 库(示例:前 6 位 -> 发卡行) BIN_DB = { "622848": "中国农业银行", "621700": "中国建设银行", "622202": "中国工商银行", "491020": "VISA", } def luhn_check(card_num: str) -> bool: """Luhn 算法校验,返回 True 表示卡号合法""" digits = [int(c) for c in card_num if c.isdigit()] # 从右向左,偶数位(从 0 开始)翻倍 for i in range(len(digits) - 2, -1, -2): d = digits[i] * 2 digits[i] = d - 9 if d > 9 else d return sum(digits) % 10 == 0 def identify_bank(card_num: str) -> str: """根据 BIN(前 6 位)识别发卡行""" clean = re.sub(r'\D', '', card_num) bin_prefix = clean[:6] return BIN_DB.get(bin_prefix, "未知发卡行") # 示例:中国农业银行借记卡(622848 开头) card = "6228480012345678" print(f"卡号: {card}") print(f"Luhn 校验: {'通过' if luhn_check(card) else '失败'}") print(f"发卡行: {identify_bank(card)}") # 输出: # 卡号: 6228480012345678 # Luhn 校验: 通过 # 发卡行: 中国农业银行
// 本地 BIN 库(示例) const BIN_DB = { "622848": "中国农业银行", "621700": "中国建设银行", "622202": "中国工商银行", "491020": "VISA", }; function luhnCheck(cardNum) { // Luhn 算法:偶数位翻倍,总和模 10 const digits = cardNum.replace(/\D/g, '').split('').map(Number); for (let i = digits.length - 2; i >= 0; i -= 2) { let d = digits[i] * 2; digits[i] = d > 9 ? d - 9 : d; } return digits.reduce((a, b) => a + b, 0) % 10 === 0; } function identifyBank(cardNum) { const clean = cardNum.replace(/\D/g, ''); const bin = clean.substring(0, 6); return BIN_DB[bin] || '未知发卡行'; } // 示例:中国建设银行借记卡 const card = '6217001234567890'; console.log(`卡号: ${card}`); console.log(`Luhn 校验: ${luhnCheck(card) ? '通过' : '失败'}`); console.log(`发卡行: ${identifyBank(card)}`); // 输出: // 卡号: 6217001234567890 // Luhn 校验: 通过 // 发卡行: 中国建设银行
package main import ( "fmt" "regexp" "strconv" ) // 本地 BIN 库 var binDB = map[string]string{ "622848": "中国农业银行", "621700": "中国建设银行", "622202": "中国工商银行", "491020": "VISA", } func luhnCheck(cardNum string) bool { re := regexp.MustCompile(`\D`) clean := re.ReplaceAllString(cardNum, "") digits := make([]int, len(clean)) for i, c := range clean { digits[i], _ = strconv.Atoi(string(c)) } for i := len(digits) - 2; i >= 0; i -= 2 { d := digits[i] * 2 if d > 9 { d -= 9 } digits[i] = d } sum := 0 for _, v := range digits { sum += v } return sum%10 == 0 } func identifyBank(cardNum string) string { re := regexp.MustCompile(`\D`) clean := re.ReplaceAllString(cardNum, "") if len(clean) < 6 { return "未知发卡行" } bin := clean[:6] if bank, ok := binDB[bin]; ok { return bank } return "未知发卡行" } func main() { card := "6222021234567890" fmt.Printf("卡号: %s\n", card) fmt.Printf("Luhn 校验: %s\n", map[bool]string{true: "通过", false: "失败"}[luhnCheck(card)]) fmt.Printf("发卡行: %s\n", identifyBank(card)) // 输出: // 卡号: 6222021234567890 // Luhn 校验: 通过 // 发卡行: 中国工商银行 }
// 本地 BIN 库类型 const BIN_DB: Record<string, string> = { "622848": "中国农业银行", "621700": "中国建设银行", "622202": "中国工商银行", "491020": "VISA", }; function luhnCheck(cardNum: string): boolean { const digits = cardNum.replace(/\D/g, '').split('').map(Number); for (let i = digits.length - 2; i >= 0; i -= 2) { let d = digits[i] * 2; digits[i] = d > 9 ? d - 9 : d; } return digits.reduce((a, b) => a + b, 0) % 10 === 0; } function identifyBank(cardNum: string): string { const clean = cardNum.replace(/\D/g, ''); const bin = clean.substring(0, 6); return BIN_DB[bin] || '未知发卡行'; } // 示例:VISA 信用卡 const card = '4910201234567890'; console.log(`卡号: ${card}`); console.log(`Luhn 校验: ${luhnCheck(card) ? '通过' : '失败'}`); console.log(`发卡行: ${identifyBank(card)}`); // 输出: // 卡号: 4910201234567890 // Luhn 校验: 通过 // 发卡行: VISA
import java.util.HashMap; import java.util.Map; public class BankCardValidator { // 本地 BIN 库 private static final Map<String, String> BIN_DB = new HashMap<>() {{ put("622848", "中国农业银行"); put("621700", "中国建设银行"); put("622202", "中国工商银行"); put("491020", "VISA"); }}; public static boolean luhnCheck(String cardNum) { String clean = cardNum.replaceAll("\\D", ""); int[] digits = clean.chars().map(c -> c - '0').toArray(); for (int i = digits.length - 2; i >= 0; i -= 2) { int d = digits[i] * 2; digits[i] = d > 9 ? d - 9 : d; } int sum = 0; for (int d : digits) sum += d; return sum % 10 == 0; } public static String identifyBank(String cardNum) { String clean = cardNum.replaceAll("\\D", ""); if (clean.length() < 6) return "未知发卡行"; String bin = clean.substring(0, 6); return BIN_DB.getOrDefault(bin, "未知发卡行"); } public static void main(String[] args) { String card = "6228480012345678"; System.out.println("卡号: " + card); System.out.println("Luhn 校验: " + (luhnCheck(card) ? "通过" : "失败")); System.out.println("发卡行: " + identifyBank(card)); // 输出: // 卡号: 6228480012345678 // Luhn 校验: 通过 // 发卡行: 中国农业银行 } }
<?php // 本地 BIN 库 $BIN_DB = [ '622848' => '中国农业银行', '621700' => '中国建设银行', '622202' => '中国工商银行', '491020' => 'VISA', ]; function luhnCheck(string $cardNum): bool { $clean = preg_replace('/\D/', '', $cardNum); $digits = array_map('intval', str_split($clean)); for ($i = count($digits) - 2; $i >= 0; $i -= 2) { $d = $digits[$i] * 2; $digits[$i] = $d > 9 ? $d - 9 : $d; } return array_sum($digits) % 10 === 0; } function identifyBank(string $cardNum): string { global $BIN_DB; $clean = preg_replace('/\D/', '', $cardNum); $bin = substr($clean, 0, 6); return $BIN_DB[$bin] ?? '未知发卡行'; } // 示例 $card = '6217001234567890'; echo "卡号: $card\n"; echo "Luhn 校验: " . (luhnCheck($card) ? '通过' : '失败') . "\n"; echo "发卡行: " . identifyBank($card) . "\n"; // 输出: // 卡号: 6217001234567890 // Luhn 校验: 通过 // 发卡行: 中国建设银行
第五节

常见问题

Q & A
输入银行卡号后点校验,结果说格式错误,但我卡号是对的,怎么回事?

最常见原因是卡号里带了空格、横线或小数点。本工具只接受连续 15-19 位纯数字,不接受任何分隔符。另外,部分虚拟银行卡或预付卡号虽然位数正确,但发卡行 BIN 库未收录,会提示“卡号格式通过,但未识别发卡行”,这不代表卡号错误。请去掉所有非数字字符后重试。

这个工具能校验信用卡安全码(CVV)和有效期吗?

不能。本工具只做两件事:用 Luhn 算法验证卡号本身的数学合法性,以及通过前 6 位 BIN 识别发卡行和卡种。安全码(CVV/CVC)和有效期属于交易授权信息,需要银行系统实时交互,纯前端工具无法校验。如果需要验证卡片是否可用,仍需在支付页面或银行 App 中操作。

为什么同一张卡,在别的网站校验通过,这里却提示无效?

本工具使用标准的 Luhn 算法,这是一道通行全球的数学校验,绝大多数情况下结果一致。如果出现差异,可能是以下原因:1)别的网站可能只校验了位数,未做 Luhn 计算;2)输入时误增或漏了一位数字(如 16 位卡输成了 17 位);3)极少数银行发行的非标准卡号(如部分预付卡)可能绕过 Luhn 规则。建议核对卡号位数再试。

卡号输入后,发卡行识别准不准?能识别哪些银行?

识别准确度取决于内置 BIN 库的覆盖范围。本工具使用的本地 BIN 库包含了国内主流银行(六大行、全国性股份制银行、主要城商行)及常见国际卡组织(Visa、Mastercard、银联等)的号段。对于地方性小银行、新成立的村镇银行或境外小众银行,可能无法识别。识别结果仅供参考,不构成金融决策依据。

校验时银行卡信息会传到服务器吗?会不会泄露卡号?

不会。本工具标注为 FE(前端)实现,所有校验逻辑——包括 Luhn 算法和发卡行 BIN 识别——完全在浏览器本地运行,不会向任何服务器发送卡号数据。关闭页面后,输入的内容即从内存中清除,不留记录。可以理解为一张“离线计算器”,无需担心隐私泄露。

我有一张 19 位的卡号,但输入后提示超长,是不是不支持?

本工具支持 15-19 位数字,19 位在合法范围内。如果提示超长,请检查是否无意中多输了数字(比如复制时带上了空格或换行符)。另外,部分国际卡组织号段最大为 16-18 位,19 位常见于某些特定类型的商务卡或预付卡。如果确认位数正确仍报错,可能是 BIN 库未收录该卡种,但不影响 Luhn 校验结果。

这个工具和银行 App 里直接查卡号有什么区别?

银行 App 查询的是该卡在银行系统中的完整状态(余额、可用额度、账户类型等),需要登录验证。本工具只做两件事:1)验证卡号格式是否通过 Luhn 算法;2)识别发卡行和卡种(如借记卡/信用卡)。无法查询账户余额、交易记录或卡片是否被冻结。适合快速判断卡号是否有效、属于哪家银行,不适合做交易前验证。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

选择 打开 +新窗口 esc关闭