Estoy tratando de crear un programa para validar 10 a 12 dígitos largo número de secuencias basado en el algoritmo de luhn, pero mi programa se mantiene en mí que me decía que cada número no es válido aun cuando no lo sean.

Este número debería ser válido, pero mi código no lo creo: 8112189876

Este número no debe ser válida, que mi programa está de acuerdo con el, ya que piensa que cada número no es válido: 8112189875

Aquí está mi código:

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!");
        }
    }
}
  • ericlippert.com/2014/03/05/how-to-debug-small-programs; el paso a través de este programa que se ejecuta con un depurador. Me pregunto si tmp tiene el valor que usted espera. "1".charAt(0) no es igual a 1. Trate de Integer.parseInt().
  • int num = tmp - 0 Bastante seguro de que esta línea devuelve el ASCII char valor más que el valor de un dígito, no?
InformationsquelleAutor Pontus | 2014-10-15

7 Comentarios

  1. 7

    La primera cosa que veo es que usted tiene:

    int num = tmp - 0

    En su lugar usted debe tener:

    int num = tmp - '0';

    En segundo lugar, usted debe validar su suma fuera de la for bucle, porque sólo se preocupan por la suma después de procesar todos los dígitos.

    En tercer lugar, que está empezando desde el final de la serie, y que no están incluidos en el primer número de su cadena. ¿Por qué no utilizar i para ambas tareas?

    Resultante (de trabajo) método:

    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!");
      }
    }

    Estilísticamente, este método sería más útil si, en lugar de la firma del método

    static void luhn() {

    lugar había firma del método

    static boolean luhn(String input) {

    Esta facilidad permite que su código para obtener el String de CUALQUIER fuente (un archivo codificado, etc.) y hacer cualquier cosa con el resultado (imprimir un mensaje como el suyo, o hacer algo más). Obviamente podría mover el System.out.print, input.nextLine(), y if(valid) bits de código fuera de este método.

    Completo refactorizado programa:

    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!");
    }
    }
    }
  2. 14

    uso org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit.LUHN_CHECK_DIGIT.isValid(number)

    Maven Dependencia:

    <dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.5.1</version>
    </dependency>
  3. 2

    Puedo utilizar esta función en una aplicación para comprobar el número de la tarjeta de validez :

    public static boolean Check(String ccNumber)
    {
    int sum = 0;
    boolean alternate = false;
    for (int i = ccNumber.length() - 1; i >= 0; i--)
    {
    int n = Integer.parseInt(ccNumber.substring(i, i + 1));
    if (alternate)
    {
    n *= 2;
    if (n > 9)
    {
    n = (n % 10) + 1;
    }
    }
    sum += n;
    alternate = !alternate;
    }
    return (sum % 10 == 0);
    }

    La esperanza de que esto ayude,

  4. 0

    Usted debe restar ‘0’ de la ptm, no 0. Restando 0, devuelve el valor ASCII, que no desea.

    • Java String, Character y char uso de Unicode/UTF-16, no ASCII.
  5. 0

    He aquí algunas de las funciones que le escribí a ambos calcular el dígito de control de un número dado y para verificar un determinado número de secuencia y extraer el número de ella.

    Para calcular el dígito de control de un número dado:

    /**
    * Generates the check digit for a number using Luhn's algorithm described in detail at the following link:
    * https://en.wikipedia.org/wiki/Luhn_algorithm
    *
    * In short the digit is calculated like so:
    * 1. From the rightmost digit moving left, double the value of every second digit. If that value is greater than 9,
    *    subtract 9 from it.
    * 2. Sum all of the digits together
    * 3. Multiply the sum by 9 and the check digit will be that value modulo 10.
    *
    * @param number the number to get the Luhn's check digit for
    * @return the check digit for the given number
    */
    public static int calculateLuhnsCheckDigit(final long number) {
    int     sum       = 0;
    boolean alternate = false;
    String  digits    = Long.toString(number);
    for (int i = digits.length() - 1; i >= 0; --i) {
    int digit = Character.getNumericValue(digits.charAt(i)); //get the digit at the given index
    digit = (alternate = !alternate) ? (digit * 2) : digit;  //double every other digit
    digit = (digit > 9)              ? (digit - 9) : digit;  //subtract 9 if the value is greater than 9
    sum += digit;                                            //add the digit to the sum
    }
    return (sum * 9) % 10;
    }

    Para verificar una secuencia de dígitos, usando el algoritmo de Luhn y extraer el número:

    /**
    * Verifies that a given number string is valid according to Luhn's algorithm, which is described in detail here:
    * https://en.wikipedia.org/wiki/Luhn_algorithm
    *
    * In short, validity of the number is determined like so:
    * 1. From the rightmost digit (the check digit) moving left, double the value of every second digit. The check
    *    digit is not doubled; the first digit doubled is the one immediately to the left of the check digit. If that
    *    value is greater than 9, subtract 9 from it.
    * 2. Sum all of the digits together
    * 3. If the sum modulo 10 is equal to 0, then the number is valid according to Luhn's algorithm
    *
    * @param luhnsNumber the number string to verify and extract the number from
    * @return an empty Optional if the given string was not valid according to Luhn's algorithm
    *         an Optional containing the number verified by Luhn's algorithm if the given string passed the check
    */
    public static Optional<Long> extractLuhnsNumber(final String luhnsNumber) {
    int     sum       = 0;
    boolean alternate = true;
    Long    number    = Long.parseLong(luhnsNumber.substring(0, luhnsNumber.length() - 1));
    for (int i = luhnsNumber.length() - 1; i >= 0; --i) {
    int digit = Character.getNumericValue(luhnsNumber.charAt(i)); //get the digit at the given index
    digit = (alternate = !alternate) ? (digit * 2) : digit;       //double every other digit
    digit = (digit > 9)              ? (digit - 9) : digit;       //subtract 9 if the value is greater than 9
    sum += digit;                                                 //add the digit to the sum
    }
    return (sum % 10 == 0) ? Optional.of(number) : Optional.empty();
    }
  6. 0

    Los recién llegados a este post/pregunta puede comprobar apropiado Página de la Wikipedia para la solución. A continuación está el código Java copia-pega desde allí.

    public class Luhn
    {
    public static boolean check(String ccNumber)
    {
    int sum = 0;
    boolean alternate = false;
    for (int i = ccNumber.length() - 1; i >= 0; i--)
    {
    int n = Integer.parseInt(ccNumber.substring(i, i + 1));
    if (alternate)
    {
    n *= 2;
    if (n > 9)
    {
    n = (n % 10) + 1;
    }
    }
    sum += n;
    alternate = !alternate;
    }
    return (sum % 10 == 0);
    }
    }
  7. 0

    Si el uso de Java 10 o superior, puede utilizar el código siguiente:

    public static boolean luhn(String s) {
    IntUnaryOperator sumDigits = n -> n / 10 + n % 10;
    var digits = s.chars()
    .map(Character::getNumericValue)
    .toArray();
    return IntStream.rangeClosed(1, digits.length)
    .map(i -> digits.length - i)
    .map(i -> i % 2 == 0 ? digits[i] : sumDigits.applyAsInt(digits[i] * 2))
    .sum() % 10 == 0;
    }

    Es el enfoque funcional a este algoritmo.

Dejar respuesta

Please enter your comment!
Please enter your name here