You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Verhoeff算法集成到JavaScript和HTML中验证信用卡输入

信用卡表单集成Verhoeff算法验证问题

我正在为入学测试编写信用卡表单的HTML与JavaScript代码,希望集成Verhoeff算法实现信用卡号验证,要求输入框失去焦点时触发验证,验证不通过时将输入框背景设为rgb(231,0,100)。自行尝试集成并查找相关方案但均失败,现有代码及尝试的集成代码如下:

现有HTML代码

<!--Debit/Credit Card input; I set the type to password as an added layer of security-->
<label for="card" data-mlr-text>Card</label>
<input type="password" id="cardBox" placeholder="Write your Credit/Debit Card here" title="Write your Credit/Debit Card number" pattern="\d{10,19}" required onfocusout=validateCard()>

现有JavaScript代码

// to validate before clicking Submit
var validName = false
var validCard = false
var validEmail = false
var validCVV = false


function validateName() {
    var name = document.getElementById("nameBox")
    var pattern = /^([^0-9]*)$/
   validName =  validate(name, pattern)
}

function validateEmail() {
   var name = document.getElementById("emailBox")
    var pattern = /\w+@\w+\.\w+$/
    validEmail = validate(name, pattern)
}

function validateCard() {
   var name = document.getElementById("cardBox")
    var pattern = /\b\d{16}$/
    validCard = validate(name, pattern)
}

function validateCVV() {
   var name = document.getElementById("cvvBox")
    var pattern = /\b\d{16}$/
    validCVV = validate(name, pattern)
}

function validate(box, pattern)
 {
  var nameVal = box.value
    if (pattern.test(nameVal)) {
        box.style.background = "white"
        return true

    } else {
        box.style.background = "rgb(231, 0, 100)"
        return false
    }
 }

function submitForm() {

 if (!validName || !validEmail || !validCard || !validCVV) {
        alert ("Please correct your input data ")
 }
}

尝试集成的Verhoeff算法代码(无法正常工作)

// multiplication table d
var d=[
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], 
    [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], 
    [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], 
    [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], 
    [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], 
    [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], 
    [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], 
    [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], 
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
];

// permutation table p
var p=[
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
    [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], 
    [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], 
    [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], 
    [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], 
    [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], 
    [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], 
    [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]
];

// inverse table inv
var inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9];

// converts string or number to an array and inverts it
function invArray(array){
    
    if (Object.prototype.toString.call(array) == "[object Number]"){
        array = String(array);
    }
    
    if (Object.prototype.toString.call(array) == "[object String]"){
        array = array.split("").map(Number);
    }
    
    return array.reverse();
    
}

// generates checksum
function generate(array){
        
    var c = 0;
    var invertedArray = invArray(array);
    
    for (var i = 0; i < invertedArray.length; i++){
        c = d[c][p[((i + 1) % 8)][invertedArray[i]]];
    }
    
    return inv[c];
}

// validates checksum
function validate(array) {
    
    var c = 0;
    var invertedArray = invArray(array);
    
    for (var i = 0; i < invertedArray.length; i++){
        c=d[c][p[(i % 8)][invertedArray[i]]];
    }

    return (c === 0);
}
var box = document.getElementById("cardBox");
if (c === 0) {
    box.style.background = "rgb(137,200,46)";
} else {
    box.style.background = "rgb(231,0,100)";
  
}

尝试的变体(仍无法运行)

function verify() {
        var box = document.getElementById("cardBox");
        if(validate(box)) {
            box.style.background = "rgb(137,200,46)";
        } else {
            box.style.background = "rgb(231,0,100)";
        }  
}

注:我是JavaScript新手,该任务考察资源整合能力而非语言知识。


问题排查与修正方案

你的代码主要存在以下几个问题:

  1. 函数命名冲突:原有代码中已有validate函数,Verhoeff算法里的同名函数会覆盖它,导致逻辑混乱。
  2. 参数传递错误:Verhoeff的验证函数需要接收卡号字符串/数字,你却传入了DOM元素,无法正确处理。
  3. 执行时机错误:全局作用域直接操作DOM会在页面未加载完成时执行,导致获取不到元素;且未关联到输入框的失焦事件。
  4. 正则规则错误:原有卡号正则限制死16位,和HTML的pattern不匹配;CVV正则完全错误。

修正后的完整代码

HTML(无需修改)

<!--Debit/Credit Card input; I set the type to password as an added layer of security-->
<label for="card" data-mlr-text>Card</label>
<input type="password" id="cardBox" placeholder="Write your Credit/Debit Card here" title="Write your Credit/Debit Card number" pattern="\d{10,19}" required onfocusout="validateCard()">

JavaScript

// to validate before clicking Submit
var validName = false
var validCard = false
var validEmail = false
var validCVV = false

// -------------------------- Verhoeff算法部分(重命名避免冲突) --------------------------
// multiplication table d
var d=[
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    [1, 2, 3, 4, 0, 6, 7, 8, 9, 5], 
    [2, 3, 4, 0, 1, 7, 8, 9, 5, 6], 
    [3, 4, 0, 1, 2, 8, 9, 5, 6, 7], 
    [4, 0, 1, 2, 3, 9, 5, 6, 7, 8], 
    [5, 9, 8, 7, 6, 0, 4, 3, 2, 1], 
    [6, 5, 9, 8, 7, 1, 0, 4, 3, 2], 
    [7, 6, 5, 9, 8, 2, 1, 0, 4, 3], 
    [8, 7, 6, 5, 9, 3, 2, 1, 0, 4], 
    [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
];

// permutation table p
var p=[
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
    [1, 5, 7, 6, 2, 8, 3, 0, 9, 4], 
    [5, 8, 0, 3, 7, 9, 6, 1, 4, 2], 
    [8, 9, 1, 6, 0, 4, 3, 5, 2, 7], 
    [9, 4, 5, 3, 1, 2, 6, 8, 7, 0], 
    [4, 2, 8, 6, 5, 7, 3, 9, 0, 1], 
    [2, 7, 9, 3, 8, 0, 6, 4, 1, 5], 
    [7, 0, 4, 6, 9, 1, 3, 2, 5, 8]
];

// inverse table inv
var inv = [0, 4, 3, 2, 1, 5, 6, 7, 8, 9];

// converts string or number to an array and inverts it
function invArray(array){
    if (Object.prototype.toString.call(array) == "[object Number]"){
        array = String(array);
    }
    if (Object.prototype.toString.call(array) == "[object String]"){
        array = array.split("").map(Number);
    }
    return array.reverse();
}

// generates checksum
function verhoeffGenerate(array){
    var c = 0;
    var invertedArray = invArray(array);
    for (var i = 0; i < invertedArray.length; i++){
        c = d[c][p[((i + 1) % 8)][invertedArray[i]]];
    }
    return inv[c];
}

// validates checksum(重命名避免冲突)
function verhoeffValidate(array) {
    var c = 0;
    var invertedArray = invArray(array);
    for (var i = 0; i < invertedArray.length; i++){
        c=d[c][p[(i % 8)][invertedArray[i]]];
    }
    return (c === 0);
}
// -------------------------- Verhoeff算法部分结束 --------------------------

function validateName() {
    var name = document.getElementById("nameBox")
    var pattern = /^([^0-9]*)$/
    validName = validate(name, pattern)
}

function validateEmail() {
    var name = document.getElementById("emailBox")
    var pattern = /\w+@\w+\.\w+$/
    validEmail = validate(name, pattern)
}

function validateCard() {
    var cardBox = document.getElementById("cardBox")
    // 先验证格式是否符合10-19位数字
    var pattern = /^\d{10,19}$/
    if (!pattern.test(cardBox.value)) {
        cardBox.style.background = "rgb(231, 0, 100)"
        validCard = false
        return
    }
    // 格式正确后再用Verhoeff算法验证
    if (verhoeffValidate(cardBox.value)) {
        cardBox.style.background = "white"
        validCard = true
    } else {
        cardBox.style.background = "rgb(231, 0, 100)"
        validCard = false
    }
}

function validateCVV() {
    var cvvBox = document.getElementById("cvvBox")
    // CVV应为3或4位数字,修正正则
    var pattern = /^\d{3,4}$/
    validCVV = validate(cvvBox, pattern)
}

function validate(box, pattern) {
    var val = box.value
    if (pattern.test(val)) {
        box.style.background = "white"
        return true
    } else {
        box.style.background = "rgb(231, 0, 100)"
        return false
    }
}

function submitForm() {
    if (!validName || !validEmail || !validCard || !validCVV) {
        alert ("Please correct your input data ")
    }
}

关键修正点说明

  1. 重命名Verhoeff函数:将原validate改为verhoeffValidate,避免和表单验证函数冲突。
  2. 修正参数传递:在validateCard中先验证卡号格式,再将卡号字符串传入Verhoeff验证函数。
  3. 关联事件逻辑:将Verhoeff验证整合到validateCard函数中,确保失焦时触发完整验证流程。
  4. 修正正则规则:卡号正则和HTML的pattern保持一致;CVV正则改为符合实际规则的/^\d{3,4}$/。
  5. 移除无效全局操作:删除原Verhoeff代码中全局作用域的DOM操作,确保代码在函数内按需执行。

内容的提问来源于stack exchange,提问作者Federico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:56:59