Programing

PHP에서 신용 카드를 확인하는 가장 좋은 방법은 무엇입니까?

lottogame 2020. 11. 13. 07:41
반응형

PHP에서 신용 카드를 확인하는 가장 좋은 방법은 무엇입니까?


신용 카드 번호가 있고 추가 정보가없는 경우 유효한 번호인지 여부를 결정하는 PHP에서 가장 좋은 방법은 무엇입니까?

지금 당장은 American Express, Discover, MasterCard 및 Visa에서 작동하는 것이 필요하지만 다른 유형에서도 작동한다면 도움이 될 수 있습니다.


카드 번호 확인에는 세 부분이 있습니다.

  1. PATTERN- 발행자 패턴과 일치합니까 (예 : VISA / Mastercard / etc.)
  2. CHECKSUM- 실제로 체크섬을 수행합니까 (예 : AMEX 카드 번호로 만들기 위해 "34"뒤에 오는 13 개의 임의의 숫자가 아님)
  3. 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 알고리즘을 사용합니다.

Wikipedia에 설명 된 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

반응형