首页 > 解决方案 > Java:如何使用 Luhn 检查和使用方法检查信用卡的有效性

问题描述

我一直在试图弄清楚这种 Luhns 验证信用卡的方法,但我似乎无法弄清楚。我需要使用方法并且不能使用数组,所以我完全被难住了。

这是 Luhns 检查:

信用卡号必须包含 13 到 16 位数字。它必须以以下开头: ■ 4 用于 Visa 卡 ■ 5 用于 Master 卡 ■ 37 用于美国运通卡 ■ 6 用于 Discover 卡

  1. 从右到左每隔一个数字加倍。如果一个数字加倍得到两位数,则将两位数相加得到一位数。
  2. 现在添加步骤 a 中的所有个位数数字。
  3. 将卡号中奇数位的所有数字从右到左相加。
  4. 将步骤 b 和步骤 c 的结果相加。
  5. 如果步骤d的结果能被10整除,则卡号有效;否则无效。例如,号码 4388576018402626 无效,但号码 4388576018410707 有效。

我的问题是我仍在学习方法(完全是初学者。我去年尝试学习编码一次并放弃了,但这次我设法做到了这一点)而且我不知道如何使用这些从 Luhn 检查中执行第 4 步和第 5 步的方法。

有人可以帮我吗?谢谢!!

public static boolean isValid(String x) {
    return false; // Stub method    
}

public static void AddResults() {

}

public static void OddDigits(String s) {
    int sum = 0;
    for (int index = 0; index < s.length(); index ++) {
        if (index % 2 != 0) {
            sum = sum + Character.getNumericValue(s.charAt(index));
        }
    }
    return;
}

public static int DoubleToSingle(int x) { // Adds up the digits in a two-digit number. 
    if (x < 10) {
        return x;
    } 
    else {
        int firstDigit = x % 10;
        int secondDigit = (int)(x / 10);
        return firstDigit + secondDigit;
    }
}

public static void Doubling(String s) {
    int sum = 0;
    for (int index = s.length() - 1; index > 0; index-= 2) {
        int parse = Character.getNumericValue(s.charAt(index));
        if (parse > 9) {
        sum = sum + DoubleToSingle(parse);
        }
        else {
            sum = sum + parse;
        }
    }

    return;
}

public static boolean CheckLength(String s) {
    if (s.length() < 13 || s.length() > 16) { // If the cc number is smaller than 13 digits or larger than 16 digits, it's invalid
        return false;
    }
    else {
        return true;
    }
}

public static String ReadString(Scanner s) { // Creating a string method. (Using it to practice creating methods)
    String x = s.nextLine();
    return x;
}

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    System.out.println("Please input a valid Credit Card number: ");
    String CC = ReadString(input);

    if (isValid(CC) == true) {
        System.out.println(CC + " is valid.");
    } else {
        System.out.println(CC + " is invalid.");
    }       
    input.close();
}

标签: javamethodsluhn

解决方案


关于您的代码的评论:

  • Java 命名约定是方法名称以小写字母开头,就像您的 isValid方法一样。

  • doubleToSingle方法中,xis an int, and10是一个int文字,所以x / 10an int, 结果会被截断,这意味着不需要这种强制转换:(int)(x / 10)

  • 由于doubleToSingle方法可以处理个位数的数字,所以调用者(方法)也不需要doubling处理,所以省去if (parse > 9)测试。

  • 从右边数数字的工作方式如下:

     5th digit       Odd places:
     ↓ 3rd digit       Don't double these digits, just sum them
     ↓ ↓ 1st digit
     ↓ ↓ ↓
    999999
    ↑ ↑ ↑
    ↑ ↑ 2nd digit    Even places, aka "every second digit from right":
    ↑ 4th digit        Double these digits, combine digits when
    6th digit          two-digit number, then sum them
    

    doubling方法从最后一个索引开始,而不是应该从倒数第二个索引开始,并且它跳过了不应该的第一个索引。循环应该是:

    for (int index = s.length() - 2; index >= 0; index -= 2)
    
  • 在调用该方法之前,该doubling方法确实需要将数字 ( )加倍parse * 2doubleToSingle

  • 该方法从左oddDigits数奇数/偶数,而它应该从右数。

    删除if (index % 2 != 0)测试,并使用doubling方法中使用的类似循环:

    for (int index = s.length() - 1; index >= 0; index -= 2)
    
  • 和方法应该是doubling,否则有什么意义呢?oddDigitsreturnsum

doubling如果认为and方法缺少返回值oddDigits是你卡住的原因,那么我会让你从这里开始处理其余的代码。


尽管以下代码超出了您当前的技能水平,但我想展示它,以便您有一些期待,能够理解并最终编写出类似的代码。

public static boolean isValid(String cc) {
    if (! cc.matches("(?=[456]|37)[0-9]{13,16}"))
        return false;
    int sum = 0;
    for (int i = cc.length() - 1, pos = 1; i >= 0; i--, pos++) {
        int digit = cc.charAt(i) - '0';
        sum += (pos % 2 == 1/*odd*/ ? digit : digit < 5 ? digit * 2 : digit * 2 - 9);
    }
    return (sum % 10 == 0);
}

它会测试问题中列出的所有条件,甚至是您尚未开始的“必须以”部分。在您的技能水平上,您可能应该使用这里使用的正则表达式s.startsWith("xx")来代替。matches(...)


推荐阅读