【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この結果が割り切れれば、ルーン・アルゴリズムで正常な値となるわけ。
正確にいうと左端から1桁飛ばしにやるのではなく、右端から数えないといけない(AmericanExpressとダイナースは桁数が違うので左から数えるとずれます)
コード
これをベースに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
まとめ
CakePHPだと標準のバリデーションが付いているので楽なのですが、CodeIgniterだと何もついてないので自前で準備しないといけなくて改良しました。