【PHP】クレジットカード番号が正しいかチェックする(アメックス・ダイナース対応版)

クレジットカード番号のチェック方法

Luhnアルゴリズムで番号生成が行われているのでかんたんなチェックロジックを実装するだけで、そのカード番号が正しいかチェックすることができます。

 

例えば、「49927398716」というカード番号だった場合、一桁飛ばしで二倍にする。

  4  9  9  2  7  3  9  8  7  1  6
  ↓*2  ↓ *2 ↓ *2 ↓ *2 ↓ *2 ↓
  4 18  9  4  7  6  9 16  7  2  6

算出した値を桁毎に足していき、10で割る。

  4 18  9  4  7  6  9 16  7  2  6
  ↓
  4189476916726
  ↓
  4+1+8+9+4+7+6+9+1+6+7+2+6
  ↓
  70
  ↓
  70/10

この結果が割り切れれば、ルーン・アルゴリズムで正常な値となるわけ。

クレジットカード番号のチェックに有効なアルゴリズム - 前向きに行こうか - craysの日記より

 

正確にいうと左端から1桁飛ばしにやるのではなく、右端から数えないといけない(AmericanExpressとダイナースは桁数が違うので左から数えるとずれます)

 

コード

【PHP】クレジットカードチェックサンプル

これをベースにAmericanExpressとダイナースクラブカードに対応させたコードです。銀聯はテストしてないので未対応になります。

 

    function check_credit_card_no($prm)
    {
        if (!empty($prm['credit_card_no'])) {
            $card = $prm['credit_card_no'];
            $check = "";

            // 数値以外はエラーを返す。
            if( !is_numeric( $card ) ){
                return false;
            }
            // カード番号が偶数桁かどうか
            $is_even = strlen($card) % 2 == 0;
            // 文字列を配列に分解
            $card = str_split($card);

            // 数字の数だけループする
            for( $i = 0; $i < 16; $i++ ){
                if($card[$i]){
                    // 偶数桁の場合、奇数の場合のみ2倍する
                    if ($is_even) {
                        if( $i % 2 == 0 ){
                            $card[$i] = $card[$i] * 2;
                        }
                    }else{
                        if ($i % 2 == 1){
                            $card[$i] = $card[$i] * 2;
                        }
                    }

                    // 2桁の場合は分割して足す
                    if( mb_strlen( $card[$i] ) != 1 ){
                        $split = str_split($card[$i]);
                        $card[$i] = $split[0] + $split[1];
                    }
                    $check += $card[$i];
                }
            }

            if( $check % 10 == 0 ){
                return true;
            } else{
                return false;
            }
        }
    }

テストデータ

クレジットカード番号カードの種類
4111111111111111 Visa
4242424242424242 Visa
4012888888881881 Visa
5555555555554444 MasterCard
5105105105105100 MasterCard
378282246310005 American Express
371449635398431 American Express
30569309025904 Diner's Club
38520000023237 Diner's Club
3530111333300000 JCB
3566002020360505 JCB

http://qiita.com/mimoe/items/8f5d9ce46b72b7fecff5より

 

まとめ

CakePHPだと標準のバリデーションが付いているので楽なのですが、CodeIgniterだと何もついてないので自前で準備しないといけなくて改良しました。