如何将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新手,该任务考察资源整合能力而非语言知识。
问题排查与修正方案
你的代码主要存在以下几个问题:
- 函数命名冲突:原有代码中已有
validate函数,Verhoeff算法里的同名函数会覆盖它,导致逻辑混乱。 - 参数传递错误:Verhoeff的验证函数需要接收卡号字符串/数字,你却传入了DOM元素,无法正确处理。
- 执行时机错误:全局作用域直接操作DOM会在页面未加载完成时执行,导致获取不到元素;且未关联到输入框的失焦事件。
- 正则规则错误:原有卡号正则限制死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 ") } }
关键修正点说明
- 重命名Verhoeff函数:将原
validate改为verhoeffValidate,避免和表单验证函数冲突。 - 修正参数传递:在
validateCard中先验证卡号格式,再将卡号字符串传入Verhoeff验证函数。 - 关联事件逻辑:将Verhoeff验证整合到
validateCard函数中,确保失焦时触发完整验证流程。 - 修正正则规则:卡号正则和HTML的
pattern保持一致;CVV正则改为符合实际规则的/^\d{3,4}$/。 - 移除无效全局操作:删除原Verhoeff代码中全局作用域的DOM操作,确保代码在函数内按需执行。
内容的提问来源于stack exchange,提问作者Federico
相关产品推荐
相关产品推荐

