我正在尝试创建一个程序来验证基于 luhn 算法的 10 到 12 位长数字序列,但我的程序一直告诉我每个数字都是无效的,即使它们不是。

这个数字应该是有效的,但是我的代码却不这样认为:8112189876
这个数字不应该是有效的,我的程序同意这一点,因为它认为每个数字都是无效的:8112189875
这是我的代码:

static void luhn(){
    System.out.print("Enter number to validate:\n");
    String pnr = input.nextLine();
    int length = pnr.length();
    int sum = 0;
    for (int i = 1, pos = length - 1; i < 10; i++, pos--){
        char tmp = pnr.charAt(pos);
        int num = tmp - 0
        int product;
        if (i % 2 != 0){
            product = num * 1;
        }
        else{
            product = num * 2;
        }
        if (product > 9)
            product -= 9;
        sum+= product;
        boolean valid = (sum % 10 == 0);
        if (valid){
            System.out.print("Valid!\r");
        }
        else{
            System.out.print("Invalid!");
        }
    }
}

最佳答案

我看到的第一件事是你有:

int num = tmp - 0

你应该有:
int num = tmp - '0';

其次,您应该在 for 循环之外验证您的总和,因为您只关心处理所有数字后的总和。

第三,您从数字的末尾开始,并且不包括字符串的第一个数字。为什么不将 i 用于这两个任务?

结果(工作)方法:
static void luhn(){
  System.out.print("Enter number to validate:\n");
  String pnr = input.nextLine();
  // this only works if you are certain all input will be at least 10 characters
  int extraChars = pnr.length() - 10;
  if (extraChars < 0) {
    throw new IllegalArgumentException("Number length must be at least 10 characters!");
  }
  pnr = pnr.substring(extraChars, 10 + extraChars);
  int sum = 0;
  // #3: removed pos
  for (int i = 0; i < pnr.length(); i++){
    char tmp = pnr.charAt(i);
    // #1: fixed the '0' problem
    int num = tmp - '0';
    int product;
    if (i % 2 != 0){
      product = num * 1;
    }
    else{
      product = num * 2;
    }
    if (product > 9)
      product -= 9;
    sum+= product;
  }
  // #2: moved check outside for loop
  boolean valid = (sum % 10 == 0);
  if (valid){
    System.out.print("Valid!\r");
  }
  else{
    System.out.print("Invalid!");
  }
}

在风格上 ,如果,而不是方法签名,则此方法将更有用
static void luhn() {

它反而有方法签名
static boolean luhn(String input) {

这很容易让您的代码从任何来源(文件、硬编码等)获取 String 并对结果执行任何操作(像您一样打印消息,或执行其他操作)。显然,您会将 System.out.printinput.nextLine()if(valid) 位代码移到此方法之外。

完全重构的程序:
import java.util.Scanner;

public class Luhn {
  private static Scanner input;

  public static void main(String... args) {
    input = new Scanner(System.in);
    System.out.print("Enter number to validate:\n");
    String pnr = input.nextLine();
    boolean result = luhn(pnr);
    printMessage(result);
    input.close();
  }

  static boolean luhn(String pnr){
    // this only works if you are certain all input will be at least 10 characters
    int extraChars = pnr.length() - 10;
    if (extraChars < 0) {
      throw new IllegalArgumentException("Number length must be at least 10 characters!");
    }
    pnr = pnr.substring(extraChars, 10 + extraChars);
    int sum = 0;
    for (int i = 0; i < pnr.length(); i++){
      char tmp = pnr.charAt(i);
      int num = tmp - '0';
      int product;
      if (i % 2 != 0){
        product = num * 1;
      }
      else{
        product = num * 2;
      }
      if (product > 9)
        product -= 9;
      sum+= product;
    }
    return (sum % 10 == 0);
  }

  private static void printMessage(boolean valid) {
    if (valid){
      System.out.print("Valid!\r");
    }
    else{
      System.out.print("Invalid!");
    }
  }
}

关于java - 我如何实现 Luhn 算法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26383926/

10-10 13:08