millancore / php-study

Grupo de estudio de PHP en https://frontend.cafe
6 stars 2 forks source link

Luhn #5

Open millancore opened 3 years ago

millancore commented 3 years ago

Introduccion

Dado un número, determine si es válido o no según la fórmula de Luhn.

El algoritmo de Luhn es una sencilla fórmula de suma de comprobación que se utiliza para validar una serie de números de identificación, como los números de las tarjetas de crédito y los números de la seguridad social canadiense.

La tarea consiste en comprobar si una cadena dada es válida.

Validación de un número Las cadenas de longitud 1 o inferior no son válidas. Los espacios están permitidos en la entrada, pero deben ser eliminados antes de la comprobación. Todos los demás caracteres que no sean dígitos no están permitidos.

Ejemplo: Numero de tarjeta valida

4539 1488 0343 6467

El primer paso del algoritmo de Luhn consiste en duplicar cada segundo dígito, empezando por la derecha.

4_3_ 1_8_ 0_4_ 6_6_

Si al duplicar el número se obtiene un número mayor que 9, entonces hay que restar 9 al producto. El resultado de nuestra duplicación:

8569 2478 0383 3437

Si la suma es divisible en partes iguales por 10, entonces el número es válido.

8+5+6+9+2+4+7+8+0+3+8+3+3+4+3+7 = 80

¡Este número es válido!

Reto:

Crear un funcion que valide numero de tarjeta siguiendo el algoritmo de Luhn

Solución

Hay varias formas de solucionar esto, si tomamos un numero de tarjeta tal como lo expone el algoritmo del Luhn debemos de leerlo de derecha a izquierda, pero podemos simplificar esta parte y con ayuda de strrev darle la vuelta al string.

Siempre viene bien recordar el operador aritmético % (Modulo), con este operador podemos obtener el restante de una división.

El paso siguiente es solo tomar los numero valores impares del arreglo (si 0 es par) por que necesitamos operar con el segundo digito de por medio, para sumarlos y comprobar por ultimo si la suma de estos numeros es modulo de 10.

Asi que en el if tomamos los numeros correspondientes a las casillas impares de nuestro string. los string en PHP se pueden recorrer como arreglos.

function luhn(string $creditCardNumber)
{
  $revCardNumber = strrev($creditCardNumber);

  $sum = 0;
  for($i = 0; $i < strlen($creditCardNumber); $i++) {
    $number = $revCardNumber[$i];

    if($i % 2 != 0) {
      $number = ($number += $number) > 9 ? $number -= 9: $number;
    }

    $sum += $number;
  }

  if($sum % 10 != 0) {
    return false;
  }

  return true;

}

Recuerda que esta linea $number = ($number += $number) > 9 ? $number -= 9: $number; es la forma corta de escribir el siguente IF

      if(($number += $number > 9)){
          $number = $number -= 9;
      } /* else {
          $number = $number;
      }*/

Pero en este modo el else sobra ya que estamos asignandole el mismo valor a la variable

alejandro088 commented 3 years ago

Cuando te refieres a "duplicar cada segundo dígito", entiendo que quieres decir, "duplicar digito de por medio". O sea, un digito si, un digito no, un digito si, un digito no, y asi sucesivamente.

millancore commented 3 years ago

@alejandro088 Así es, pero en ese caso comenzando por el segundo dígito de derecha a izquierda y continuando uno de por medio.