PHP에서 신용 카드를 확인하는 가장 좋은 방법은 무엇입니까?
신용 카드 번호가 있고 추가 정보가없는 경우 유효한 번호인지 여부를 결정하는 PHP에서 가장 좋은 방법은 무엇입니까?
지금 당장은 American Express, Discover, MasterCard 및 Visa에서 작동하는 것이 필요하지만 다른 유형에서도 작동한다면 도움이 될 수 있습니다.
카드 번호 확인에는 세 부분이 있습니다.
- PATTERN- 발행자 패턴과 일치합니까 (예 : VISA / Mastercard / etc.)
- CHECKSUM- 실제로 체크섬을 수행합니까 (예 : AMEX 카드 번호로 만들기 위해 "34"뒤에 오는 13 개의 임의의 숫자가 아님)
- REALLY EXISTS- 실제로 연결된 계정이 있습니까 (상인 계정 없이는 얻을 수 없음)
무늬
- MASTERCARD 접두사 = 51-55, 길이 = 16 (Mod10 체크섬)
- VISA 접두사 = 4, 길이 = 13 또는 16 (Mod10)
- AMEX 접두사 = 34 또는 37, 길이 = 15 (Mod10)
- Diners Club / Carte 접두어 = 300-305, 36 또는 38, 길이 = 14 (Mod10)
- Prefix = 6011,622126-622925,644-649,65, Length = 16, (Mod10) 발견
- 등 ( 접두사 세부 목록 )
체크섬
대부분의 카드는 체크섬에 Luhn 알고리즘을 사용합니다.
PHP를 포함하여 Wikipedia 링크에는 여러 구현에 대한 링크가 있습니다.
<?
/* 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;
}
?>
에서 10 정규 표현식 당신은 PHP에서 없이는 살 수 있습니다 :
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");
더 많은 이론적 정보는 여기에서 찾을 수 있습니다.
다음을 사용하여 신용 카드를 확인할 수 있습니다. 그것은 나를 위해 완벽하게 작동합니다.
protected function luhn($number)
{
// Force the value to be a string as this method uses string functions.
// Converting to an integer may pass PHP_INT_MAX and result in an error!
$number = (string)$number;
if (!ctype_digit($number)) {
// Luhn can only be used on numbers!
return FALSE;
}
// Check number length
$length = strlen($number);
// Checksum of the card number
$checksum = 0;
for ($i = $length - 1; $i >= 0; $i -= 2) {
// Add up every 2nd digit, starting from the right
$checksum += substr($number, $i, 1);
}
for ($i = $length - 2; $i >= 0; $i -= 2) {
// Add up every 2nd digit doubled, starting from the right
$double = substr($number, $i, 1) * 2;
// Subtract 9 from the double where value is greater than 10
$checksum += ($double >= 10) ? ($double - 9) : $double;
}
// If the checksum is a multiple of 10, the number is valid
return ($checksum % 10 === 0);
}
protected function ValidCreditcard($number)
{
$card_array = array(
'default' => array(
'length' => '13,14,15,16,17,18,19',
'prefix' => '',
'luhn' => TRUE,
),
'american express' => array(
'length' => '15',
'prefix' => '3[47]',
'luhn' => TRUE,
),
'diners club' => array(
'length' => '14,16',
'prefix' => '36|55|30[0-5]',
'luhn' => TRUE,
),
'discover' => array(
'length' => '16',
'prefix' => '6(?:5|011)',
'luhn' => TRUE,
),
'jcb' => array(
'length' => '15,16',
'prefix' => '3|1800|2131',
'luhn' => TRUE,
),
'maestro' => array(
'length' => '16,18',
'prefix' => '50(?:20|38)|6(?:304|759)',
'luhn' => TRUE,
),
'mastercard' => array(
'length' => '16',
'prefix' => '5[1-5]',
'luhn' => TRUE,
),
'visa' => array(
'length' => '13,16',
'prefix' => '4',
'luhn' => TRUE,
),
);
// Remove all non-digit characters from the number
if (($number = preg_replace('/\D+/', '', $number)) === '')
return FALSE;
// Use the default type
$type = 'default';
$cards = $card_array;
// Check card type
$type = strtolower($type);
if (!isset($cards[$type]))
return FALSE;
// Check card number length
$length = strlen($number);
// Validate the card length by the card type
if (!in_array($length, preg_split('/\D+/', $cards[$type]['length'])))
return FALSE;
// Check card number prefix
if (!preg_match('/^' . $cards[$type]['prefix'] . '/', $number))
return FALSE;
// No Luhn check required
if ($cards[$type]['luhn'] == FALSE)
return TRUE;
return $this->luhn($number);
}
luhn 알고리즘은 (... 또한 캐나다 사회 보험 번호) 신용 카드 형식의 많은의 형식을 확인하는 데 사용 할 수있는 검사입니다
위키 백과 문서는 또한 다양한 구현에 대한 링크입니다. 다음은 PHP입니다.
http://planzero.org/code/bits/viewcode.php?src=luhn_check.phps
많은 재무 번호의 유효성 검사와 신용 카드 유효성 검사를 처리하는 PEAR 패키지가 있습니다. http://pear.php.net/package/Validate_Finance_CreditCard
그건 그렇고, 여기 PayPal의 테스트 신용 카드 계정 번호 가 있습니다.
Just throwing in some further code snippets that others may find useful (not PHP code).
PYTHON (single line code; probably not that efficient)
To validate:
>>> 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
To return the required check digit:
>>> (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 Functions
Functions "ccc" and "ccd" (credit-card-check and credit-card-digit)
Note that the "ccc" function has an additional check where if the calculated sum is 0, the returned result will always be FALSE, so an all zero CC number will never validate as being correct (under normal behaviour, it would validate correctly). This feature can be added/removed as required; maybe useful, depending on specific requirements.
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;
Functions can then be used directly in SQL queries:
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)
This is only to make sure that the numbers are valid using some basic RegEX patterns.
Note, this does not check to see if the numbers are in-use by someone.
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' 카테고리의 다른 글
도킹이 해제되면 Android 스튜디오의 '미리보기'설정에 '도킹 모드'옵션이 없습니다. (0) | 2020.11.13 |
---|---|
Windows에서 ack 라이브러리를 어떻게 설치하고 사용할 수 있습니까? (0) | 2020.11.13 |
Log4Net : 롤링 파일 어 펜더, 확장 정의 (0) | 2020.11.13 |
폴더 크기는 어떻게 계산합니까? (0) | 2020.11.13 |
모든 공백을 밑줄로 안전하게 루비로 바꾸는 방법은 무엇입니까? (0) | 2020.11.13 |