PHP에서 신용카드를 검증하는 가장 좋은 방법은 무엇입니까?
신용 카드 번호와 추가 정보가 없는 경우, PHP에서 유효한 번호인지 아닌지를 판단하는 가장 좋은 방법은 무엇입니까?
지금은 American Express, Discover, Master Card, Visa에 대응 가능한 것이 필요하지만, 다른 타입에도 대응하면 도움이 될지도 모릅니다.
카드 번호의 검증에는, 다음의 3개의 부분이 있습니다.
- 패턴 - 발행자 패턴(VISA/Mastercard 등)과 일치합니까?
- CHECKSUM - 실제로 체크섬을 실행합니까(예를 들어 AMEX 카드 번호로 만들기 위해 "34" 뒤에 13개의 랜덤 번호뿐 아니라)
- REALLY EXISTES - 실제로 연결된 계정이 있습니까(가맹점 계정이 없으면 이 계정을 얻을 수 없습니다).
양식
- MASTERCARD 프리픽스=51-55, 길이=16(Mod10 체크섬)
- VISA 접두사=4, 길이=13 또는 16(Mod10)
- AMEX 프리픽스=34 또는 37, 길이=15(Mod10)
- 다이너스 클럽/카트 프리픽스=300-305, 36 또는 38, 길이=14(Mod10)
- 검색 접두사=6011,622126-622925,644-649,65,길이=16, (Mod10)
- etc(프리픽스 목록 표시)
체크섬
대부분의 카드는 체크섬에 Luhn 알고리즘을 사용합니다.
Wikipedia 링크에는 PHP를 포함한 많은 구현에 대한 링크가 있습니다.
<?
/* 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;
}
?>
function check_cc($cc, $extra_check = false){
$cards = array(
"visa" => "(4\d{12}(?:\d{3})?)",
"amex" => "(3[47]\d{13})",
"jcb" => "(35[2-8][89]\d\d\d{10})",
"maestro" => "((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)",
"solo" => "((?:6334|6767)\d{12}(?:\d\d)?\d?)",
"mastercard" => "(5[1-5]\d{14})",
"switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)\d{12})|(?:(?:564182|633110)\d{10})(\d\d)?\d?)",
);
$names = array("Visa", "American Express", "JCB", "Maestro", "Solo", "Mastercard", "Switch");
$matches = array();
$pattern = "#^(?:".implode("|", $cards).")$#";
$result = preg_match($pattern, str_replace(" ", "", $cc), $matches);
if($extra_check && $result > 0){
$result = (validatecard($cc))?1:0;
}
return ($result>0)?$names[sizeof($matches)-2]:false;
}
입력 예:
$cards = array(
"4111 1111 1111 1111",
);
foreach($cards as $c){
$check = check_cc($c, true);
if($check!==false)
echo $c." - ".$check;
else
echo "$c - Not a match";
echo "<br/>";
}
이것은 우리에게
4111 1111 1111 1111 - 비자
고객측에서는 코드로 검증하지 않는 것이 좋을지도 모릅니다.카드 정보를 바로 결제 게이트웨이로 전송한 후 답변을 처리하십시오.Luhn과 같은 작업을 먼저 수행하지 않으면 부정행위를 탐지할 수 있습니다. 실패한 시도를 확인할 수 있습니다.
PHP 코드
function validateCC($cc_num, $type) {
if($type == "American") {
$denum = "American Express";
} elseif($type == "Dinners") {
$denum = "Diner's Club";
} elseif($type == "Discover") {
$denum = "Discover";
} elseif($type == "Master") {
$denum = "Master Card";
} elseif($type == "Visa") {
$denum = "Visa";
}
if($type == "American") {
$pattern = "/^([34|37]{2})([0-9]{13})$/";//American Express
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}
} elseif($type == "Dinners") {
$pattern = "/^([30|36|38]{2})([0-9]{12})$/";//Diner's Club
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}
} elseif($type == "Discover") {
$pattern = "/^([6011]{4})([0-9]{12})$/";//Discover Card
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}
} elseif($type == "Master") {
$pattern = "/^([51|52|53|54|55]{2})([0-9]{14})$/";//Mastercard
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}
} elseif($type == "Visa") {
$pattern = "/^([4]{1})([0-9]{12,15})$/";//Visa
if (preg_match($pattern,$cc_num)) {
$verified = true;
} else {
$verified = false;
}
}
if($verified == false) {
//Do something here in case the validation fails
echo "Credit card invalid. Please make sure that you entered a valid <em>" . $denum . "</em> credit card ";
} else { //if it will pass...do something
echo "Your <em>" . $denum . "</em> credit card is valid";
}
}
사용.
echo validateCC("1738292928284637", "Dinners");
자세한 신학적 정보는 다음 URL에서 확인할 수:
luhn 알고리즘은 많은 신용 카드 형식(및 캐나다의 사회 보험 번호)의 형식을 검증하는 데 사용할 수 있는 체크섬입니다.
Wikipedia 기사에는 다양한 구현에 대한 링크도 있습니다.다음은 PHP입니다.
http://planzero.org/code/bits/viewcode.php?src=luhn_check.phps
PEAR 패키지는 다수의 재무번호 검증과 신용카드 검증을 처리합니다.http://pear.php.net/package/Validate_Finance_CreditCard
참고로 여기 페이팔의 테스트 신용카드 계좌번호가 있습니다.
다른 사람들이 유용하다고 생각할 수 있는 코드 스니펫을 추가해 주세요(PHP 코드가 아닙니다).
PYTON(단일 회선 코드. 효율이 높지 않을 수 있음)
검증 방법:
>>> 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
MySQL 함수
"ccc" 및 "ccd" 함수(신용 카드 체크 및 신용 카드 번호)
"ccc" 함수에는 계산된 합계가 0인 경우 반환된 결과는 항상 FALSE이므로 모두 0인 CC 번호는 올바른 것으로 검증되지 않습니다(정상 동작에서는 올바르게 검증됩니다).이 기능은 필요에 따라 추가/삭제할 수 있습니다.특정 요건에 따라서는 편리할 수 있습니다.
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)
이는 몇 가지 기본적인 RegEX 패턴을 사용하여 숫자가 유효한지 확인하기 위한 것입니다.
이것은, 다른 사람이 그 번호를 사용하고 있는지 어떤지는 확인하지 않습니다.
http://www.roscripts.com/How_to_validate_credit_card_numbers-106.html
언급URL : https://stackoverflow.com/questions/174730/what-is-the-best-way-to-validate-a-credit-card-in-php
'programing' 카테고리의 다른 글
| 이전 쿼리 결과에 따라 테이블을 업데이트하는 중 (0) | 2022.12.07 |
|---|---|
| Python에서 파일 크기를 가져오고 있습니까? (0) | 2022.11.27 |
| VueJS - 커스텀 요소 등록 방법 , , , (0) | 2022.11.27 |
| MySQL - 왜 php MyAdmin이 매우 빠른 쿼리에서 매우 느린가? (0) | 2022.11.27 |
| MySQL 그룹 기준 및 기타 열의 합계 값 (0) | 2022.11.27 |