<?
/* Luhn algorithm number checker - (c) 2005-2008 shaman - www.planzero.org *
* This code has been released into the public domain, however please *
* give credit to the original author where possible. */
function luhn_check($number) {
// Strip any non-digits (useful for credit card numbers with spaces and hyphens)
$number=preg_replace('/\D/', '', $number);
// Set the string length and parity
$number_length=strlen($number);
$parity=$number_length % 2;
// Loop through each digit and do the maths
$total=0;
for ($i=0; $i<$number_length; $i++) {
$digit=$number[$i];
// Multiply alternate digits by two
if ($i % 2 == $parity) {
$digit*=2;
// If the sum is two digits, add them together (in effect)
if ($digit > 9) {
$digit-=9;
}
}
// Total up the digits
$total+=$digit;
}
// If the total mod 10 equals 0, the number is valid
return ($total % 10 == 0) ? TRUE : FALSE;
}
?>
>>> not(sum(map(int, ''.join(str(n*(i%2+1)) for i, n in enumerate(map(int, reversed('1234567890123452'))))))%10)
True
>>> not(sum(map(int, ''.join(str(n*(i%2+1)) for i, n in enumerate(map(int, reversed('1234567890123451'))))))%10)
False
要返回所需的校验位:
>>> (10-sum(map(int, ''.join(str(n*(i%2+1)) for i, n in enumerate(map(int, reversed('123456789012345')), start=1)))))%10
2
>>> (10-sum(map(int, ''.join(str(n*(i%2+1)) for i, n in enumerate(map(int, reversed('234567890123451')), start=1)))))%10
1
DROP FUNCTION IF EXISTS ccc;
DROP FUNCTION IF EXISTS ccd;
DELIMITER //
CREATE FUNCTION ccc (n TINYTEXT) RETURNS BOOL
BEGIN
DECLARE x TINYINT UNSIGNED;
DECLARE l TINYINT UNSIGNED DEFAULT length(n);
DECLARE i TINYINT UNSIGNED DEFAULT l;
DECLARE s SMALLINT UNSIGNED DEFAULT 0;
WHILE i > 0 DO
SET x = mid(n,i,1);
IF (l-i) mod 2 = 1 THEN
SET x = x * 2;
END IF;
SET s = s + x div 10 + x mod 10;
SET i = i - 1;
END WHILE;
RETURN s != 0 && s mod 10 = 0;
END;
CREATE FUNCTION ccd (n TINYTEXT) RETURNS TINYINT
BEGIN
DECLARE x TINYINT UNSIGNED;
DECLARE l TINYINT UNSIGNED DEFAULT length(n);
DECLARE i TINYINT UNSIGNED DEFAULT l;
DECLARE s SMALLINT UNSIGNED DEFAULT 0;
WHILE i > 0 DO
SET x = mid(n,i,1);
IF (l-i) mod 2 = 0 THEN
SET x = x * 2;
END IF;
SET s = s + x div 10 + x mod 10;
SET i = i - 1;
END WHILE;
RETURN ceil(s/10)*10-s;
END;
然后可以在SQL查询中直接使用函数:
mysql> SELECT ccc(1234567890123452);
+-----------------------+
| ccc(1234567890123452) |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
mysql> SELECT ccc(1234567890123451);
+-----------------------+
| ccc(1234567890123451) |
+-----------------------+
| 0 |
+-----------------------+
1 row in set (0.00 sec)
mysql> SELECT ccd(123456789012345);
+----------------------+
| ccd(123456789012345) |
+----------------------+
| 2 |
+----------------------+
1 row in set (0.00 sec)
mysql> SELECT ccd(234567890123451);
+----------------------+
| ccd(234567890123451) |
+----------------------+
| 1 |
+----------------------+
1 row in set (0.00 sec)
9 回答
验证卡号有三个部分:
PATTERN - 是否与发行人模式相匹配(例如VISA / Mastercard /等)
CHECKSUM - 它实际上是检查总和(例如,在"34"之后不只是13个随机数使其成为AMEX卡号)
REALLY EXISTS - 它实际上是否有关联帐户(如果没有商家帐户,您不太可能获得此帐户)
模式
MASTERCARD前缀= 51-55,长度= 16(Mod10校验和)
VISA前缀= 4,长度= 13或16(Mod10)
AMEX前缀= 34或37,长度= 15(Mod10)
Diners Club / Carte Prefix = 300-305,36或38,长度= 14(Mod10)
发现前缀= 6011,622126-622925,644-649,65,长度= 16,(Mod10)
等(detailed list of prefixes)
校验和
大多数卡使用Luhn算法进行校验和:
Luhn Algorithm described on Wikipedia
维基百科链接上有许多实现的链接,包括PHP:
来自10 regular expressions you can't live without in PHP:
样本输入:
这给了我们
最好不要在最后验证代码 . 将卡信息直接发送到您的支付网关,然后处理他们的回复 . 如果你不先做Luhn检查,那么它可以帮助他们检测欺诈行为 - 让他们看到失败的尝试 .
PHP Code
用法
More theoric information can be found here:
Credit Card Validation - Check Digits
Checksum
我们可以使用以下方法验证信用卡 . 它对我来说很完美 .
luhn algorithm是一个校验和,可用于验证许多信用卡格式的格式(以及加拿大社会保险号码......)
维基百科文章还链接到许多不同的实现;这是一个PHP:
http://planzero.org/code/bits/viewcode.php?src=luhn_check.phps
有一个PEAR包处理许多财务数字的验证,还有信用卡验证:http://pear.php.net/package/Validate_Finance_CreditCard
顺便说一句,这是PayPal的一些Test Credit Card Account Numbers .
只是抛出一些其他人可能觉得有用的代码片段(不是PHP代码) .
PYTHON (单行代码;可能效率不高)
验证:
要返回所需的校验位:
MySQL Functions
功能“ccc”和“ccd”(信用卡支票和信用卡号码)
请注意,“ccc”函数有一个额外的检查,如果计算的和为0,则返回的结果将始终为FALSE,因此全零的CC编号永远不会验证为正确(在正常行为下,它将正确验证) . 可以根据需要添加/删除此功能;可能有用,具体取决于具体要求 .
然后可以在SQL查询中直接使用函数:
这只是为了确保使用一些基本的RegEX模式使数字有效 .
请注意,这不会检查这些号码是否正在被某人使用 .
http://www.roscripts.com/How_to_validate_credit_card_numbers-106.html