Java
 Computer >> コンピューター >  >> プログラミング >> Java

【Java】Luhnアルゴリズムでクレジットカード番号の有効性を検証するプログラム

クレジットカード番号の桁を含む長い数値が与えられたとき、その番号が有効かどうかをプログラムで判定する方法を解説します。

クレジットカード番号の有効性を確認するには、以下の検証条件をすべて満たしている必要があります。

クレジットカード番号の基本ルール

クレジットカード番号は13桁〜16桁で構成され、カードブランドごとに決まった数字で始まります。

  • Visaカード:すべて「4」から始まる
  • MasterCard:すべて「5」から始まる
  • American Expressカード:「37」から始まる
  • Discoverカード:すべて「6」から始まる

有効性チェックの手順(Luhnアルゴリズム)

カード番号が有効かどうかは、以下のステップで判定します。

  1. ステップ1:右から左に向かって各桁を2倍にします。2倍した結果が1桁ならそのまま使い、2桁になった場合は各桁を足して1桁の数にします(例:22 → 2 + 2 = 4)。
  2. ステップ2:カード番号の右から左に向かって、奇数位置にあるすべての桁を合計します。
  3. ステップ3:ステップ1で求めたすべての1桁の数値を合計します。
  4. ステップ4:ステップ2とステップ3の結果を合計します。
  5. ステップ5:合計が10で割り切れればカード番号は有効、割り切れなければ無効と判定します。

実行例

入力:n = 4440967484181607
出力:4440967484181607 は有効

入力:n = 379354508162306
出力:379354508162306 は有効

問題を解くためのアプローチ

本記事では、Luhnチェック(モジュラス10チェック)を使用して、番号「4440967484181607」の有効性を検証します。この手法は実際の決済システムでも広く使われている標準的なチェック方式です。

アルゴリズム

開始
 ステップ1 → main(String[] args) 関数内で:
  変数 cnumber を 4440967484181607L として宣言・初期化する
  validitychk 関数を呼び出す
  結果を出力する
 ステップ2 → validitychk(long cnumber) 関数内で:
  thesize(cnumber) >= 13 かつ thesize(cnumber) <= 16 であり、
  prefixmatch(cnumber, 4) または prefixmatch(cnumber, 5) または
  prefixmatch(cnumber, 37) または prefixmatch(cnumber, 6) のいずれかが成立し、
  かつ (sumdoubleeven(cnumber) + sumodd(cnumber)) % 10 == 0 であることを返す
 ステップ3 → sumdoubleeven(long cnumber) 関数内で:
  sum = 0、num = cnumber + "" として初期化する
  i = thesize(cnumber) - 2 から i >= 0 まで i -= 2 ずつ繰り返し:
   sum += getDigit(Integer.parseInt(num.charAt(i) + "") * 2)
  sum を返す
 ステップ4 → getDigit(int cnumber) 関数内で:
  cnumber < 9 の場合は cnumber をそのまま返す
  それ以外は cnumber / 10 + cnumber % 10 を返す
 ステップ5 → sumodd(long cnumber) 関数内で:
  sum = 0、num = cnumber + "" として設定する
  i = thesize(cnumber) - 1 から i >= 0 まで i -= 2 ずつ繰り返し:
   sum += Integer.parseInt(num.charAt(i) + "")
  sum を返す
 ステップ6 → prefixmatch(long cnumber, int d) 関数内で:
  getprefx(cnumber, thesize(d)) == d を返す
 ステップ7 → thesize(long d) 関数内で:
  num = d + "" と設定し、num.length() を返す
 ステップ8 → getprefx(long cnumber, int k) 関数内で:
  thesize(cnumber) > k の場合:
   num = cnumber + "" と設定し、Long.parseLong(num.substring(0, k)) を返す
  cnumber を返す
終了

Javaによる完全な実装コード

import java.util.Scanner;
public class Main {
    // メインメソッド
    public static void main(String[] args) {
        long cnumber = 4440967484181607L;
        System.out.println(cnumber + " は " + (validitychk(cnumber) ? "有効" : "無効"));
    }
    // カード番号が有効な場合にtrueを返す
    public static boolean validitychk(long cnumber) {
        return (thesize(cnumber) >= 13 && thesize(cnumber) <= 16) && (prefixmatch(cnumber, 4)
            || prefixmatch(cnumber, 5) || prefixmatch(cnumber, 37) || prefixmatch(cnumber, 6))
            && ((sumdoubleeven(cnumber) + sumodd(cnumber)) % 10 == 0);
    }
    // ステップ2の結果を取得する
    public static int sumdoubleeven(long cnumber) {
        int sum = 0;
        String num = cnumber + "";
        for (int i = thesize(cnumber) - 2; i >= 0; i -= 2)
            sum += getDigit(Integer.parseInt(num.charAt(i) + "") * 2);
        return sum;
    }
    // 1桁の場合はそのまま返し、2桁の場合は各桁の合計を返す
    public static int getDigit(int cnumber) {
        if (cnumber < 9)
            return cnumber;
        return cnumber / 10 + cnumber % 10;
    }
    // 奇数位置の桁の合計を返す
    public static int sumodd(long cnumber) {
        int sum = 0;
        String num = cnumber + "";
        for (int i = thesize(cnumber) - 1; i >= 0; i -= 2)
            sum += Integer.parseInt(num.charAt(i) + "");
        return sum;
    }
    // dがcnumberの接頭辞である場合にtrueを返す
    public static boolean prefixmatch(long cnumber, int d) {
        return getprefx(cnumber, thesize(d)) == d;
    }
    // dの桁数を返す
    public static int thesize(long d) {
        String num = d + "";
        return num.length();
    }
    // 数値の先頭k桁を返す。
    // 桁数がk未満の場合は元の数値を返す。
    public static long getprefx(long cnumber, int k) {
        if (thesize(cnumber) > k) {
            String num = cnumber + "";
            return Long.parseLong(num.substring(0, k));
        }
        return cnumber;
    }
}

出力結果

4440967484181607 は 有効

このように、Luhnアルゴリズムを実装することで、桁数チェック・ブランドごとの先頭番号チェック・チェックサム検証を組み合わせた、信頼性の高いクレジットカード番号の妥当性検証が可能になります。入力フォームのバリデーションなど、さまざまな場面で応用できるので、ぜひ参考にしてください。

  1. 【Java】素数を判定して次の素数を見つけるプログラムの作り方

    素数とは? 素数とは、1より大きい整数のうち、約数が「1」と「その数自身」の2つだけを持つ数のことです。それ以外の正の約数は一切持ちません。たとえば7は「7 = 1 × 7」としか分解できないため、素数です。 素数判定のアルゴリズム ある数が素数かどうかを調べるには、以下の手順が基本になります。 判定対象の整数を変数Aに代入する。 Aを2からA−1までの整数で順番に割っていく。 途中で一度でも割り切れたら、Aは素数ではない。 最後まで割り切れる数が現れなければ、Aは素数である。 なお、実際のプログラムでは「√Aまで調べれば十分」という性質を利用すると処理を大幅に高速化できます。これは、A

  2. Pythonでクレジットカード番号の有効性をチェックする方法

    クレジットカード番号が与えられたとき、その番号が有効かどうかを判定するPythonプログラムを作成してみましょう。有効なカード番号とみなされるには、以下の条件をすべて満たしている必要があります。先頭は4、5、6のいずれかで始まる全体で16桁である数字のみで構成されている数字を4桁ずつ4つのグループに分け、「-(ハイフン)」で区切ってもよいスペースやアンダースコアなど、ハイフン以外の区切り文字は使用できない同じ数字が4桁以上連続してはならないたとえば、入力が s = 5423-2578-8632-6589 の場合を考えてみます。この番号は先頭が5で始まり、合計16桁、4桁×4グループがハイフンで