lunes, 18 de julio de 2011

Algoritmo Luhn para validación de tarjetas de crédito



Hola a todos, bueno hace tiempo que tenia curiosidad en saber la forma en la que las tarjetas de crédito son validadas, pues bien, navegando un poco por internet me encontré que el algoritmo utilizado para la validación de tarjetas de crédito es el algoritmo de Luhn.


Este algoritmo es simple, que nos dice que dada un número que contenga solamente dígitos [0-9], es una tarjeta de crédito válida si y solo si, obteniendo la reversa de este número, y la suma sus dígitos de una forma que les explicaré en un momente debe ser un múltiplo de 10, es decir que la suma módulo 10 debe ser igual a cero.


Pues bien, la forma en sumar es la siguiente, una vez hayamos invertido el número, si es posición impar, sumamos el dígito, si es posición impar, multiplicamos ese dígito por dos y sumamos los dígitos de ese número, para hacerlo más práctico, si el doble de ese dígito es mayor o igual a 10, le restamos 9 a ese doble, bueno y finalemente se debe verificar que la suma que se realizó sea un múltiplo de 10.


Bueno, un código que realicé puede ser una forma de plasmar este algoritmo en código, por cuestiones de memoria preferí utilizar cadenas en vez de divisiones y módulos entre diez, y operaciones a nivel de bits para la multiplicación por dos.




/* 
 * Codigo fuente que implementa el algoritmo Luhn
 * que es utilizado para la validación de tarjetas
 * de credito.
 */
using System;
class LuhnValidator {
 public static void Main(string[] args) {
  string numeroTarjeta;
  // Obviamente la entrada debe ser puros digitos
  numeroTarjeta = Console.ReadLine().Trim();
  
  if(VerificarTarjeta(numeroTarjeta)) {
   Console.WriteLine("El numero {0} es valido.", numeroTarjeta);
  }
  else {
   Console.WriteLine("El numero {0} es invalido.", numeroTarjeta);
  }
  
  Console.Read();
 }
 public static bool VerificarTarjeta(string tarjeta) {
  int suma = 0;
  bool flag = true;
  
  for(int i = tarjeta.Length - 1; i >= 0; i--) {
   if(!flag) {
    int tmp = (tarjeta[i] - '0') << 1;
    suma += tmp >= 10? tmp - 9 : tmp;
   }
   else {
    suma += (tarjeta[i] - '0');
   }
   flag = !flag;
  }
  return suma % 10 == 0;
 }
}



Bueno, olvide mencionar antes que este no solo se utiliza para validar tarjetas de crédito ya que si se introduce cualquier otra secuencia de números que no sea posible verla en una tarjeta de crédito puede también ser válida, este algoritmo tiene distinas aplicaciones, por ejemplo sirve para validar el número IMEI de los teléfonos celulares, hagan la prueba y lo verán. Las tarjeta de crédito tienes un dígito de validácion, por ejemplo si una posible tarjeta comienza con el número 6 quiere decir que es una Discovery, si es 5 Master Card, si es 4 es una Visa y si es 3 es una American Express.


Nota.- Algunas de las operaciones utilizadas en el código fueron las siguientes:
x = 2;
x = x << 1 es lo mismo que x = x * 2


y una resta entre número y caracter devuelve el numero representado como caracter, por ejemplo si tenemos la cadena "123", y queremos obtener el valor de la posición 1, entonces lo que hacemos es el ASCII menos el ASCII de '0'


ascii('2') = 50
ascii('0') = 48


50 - 48 = 2


Bueno espero que les sea de utilidad.

2 comentarios:

  1. Traté de correr tu programa, pero me salen algunos campos como...
    "Utilice la palabra clave 'new' para crear una instancia de objeto"

    Tanto en el For, como "numeroTarjeta = Console.ReadLine().Trim();"

    Mi correo es: tacanin91@yahoo.com
    ¿Podrías corregir eso, o ayudarme a corregirlo?

    ResponderEliminar
  2. Muchas gracias por el código. Es realmente de utilidad.

    Saludos

    ResponderEliminar