Página 1 de 2

Algoritmo de Luhn

NotaPublicado: 2014-01-07 15:08 @672
por BigBear
¿ Hay algún script en perl ya hecho de cómo generar con números de 6 dígitos usando el algoritmo de Luhn ?

Encontré este módulo: http://search.cpan.org/~tayers/Algorith ... 00/LUHN.pm , pero solo sirve para verificar.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-07 15:56 @706
por explorer
Usa la función check_digit() del módulo Algorithm::LUHN.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-14 17:07 @755
por BigBear
Ya lo probé y solo sirve para verificar.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-14 17:26 @768
por BigBear
Perdón por el doble mensaje, pero encontré algo así ya hecho en Python:

Sintáxis: [ Descargar ] [ Ocultar ]
Using python Syntax Highlighting
  1. from random import Random
  2. import copy
  3. generator = Random()
  4. generator.seed()
  5.  
  6. def creditcard(type=""):
  7.         def credit_card_number(generator, prefixList, length):
  8.             def _completed_number(prefix, length):
  9.                 ccnumber = prefix
  10.                 while len(ccnumber) < (length - 1):
  11.                     digit = generator.choice(['0',  '1', '2', '3', '4', '5', '6', '7', '8', '9'])
  12.                     ccnumber.append(digit)
  13.                 sum, pos = (0, 0)
  14.                 reversedCCnumber = []
  15.                 reversedCCnumber.extend(ccnumber)
  16.                 reversedCCnumber.reverse()
  17.                 while pos < length - 1:
  18.                     odd = int( reversedCCnumber[pos] ) * 2
  19.                     if odd > 9:
  20.                         odd -= 9
  21.                     sum += odd
  22.                     if pos != (length - 2):
  23.                         sum += int( reversedCCnumber[pos+1] )
  24.                     pos += 2
  25.                 checkdigit = ((sum / 10 + 1) * 10 - sum) % 10
  26.                 ccnumber.append( str(checkdigit) )
  27.                 return ''.join(ccnumber)
  28.             result = []
  29.             ccnumber = copy.copy( generator.choice(prefixList) )
  30.             result.append( _completed_number(ccnumber, length) )
  31.             return result
  32.              
  33.         if type in "visa":
  34.             visaPrefixList = [['4','0','2','4', '0', '0', '7', '1'],]
  35.             return credit_card_number(generator, visaPrefixList, 16)
  36.         elif type is "amex":
  37.             amexPrefixList = [['3','4'],['3', '7']]
  38.             return credit_card_number(generator, amexPrefixList, 16)
  39.         elif type is "discover":
  40.             discoverPrefixList = [['6','0','1','1']]
  41.             return credit_card_number(generator, discoverPrefixList, 16)
  42.         elif type is "mastercard":
  43.             mastercardPrefixList = [['5','1'],['5','2'],['5','3'],['5','4'],['5','5']]
  44.             return credit_card_number(generator, mastercardPrefixList, 16)
  45.  
  46.  
  47. print creditcard("visa");
  48.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-14 17:26 @768
por explorer
No. check_digit() devuelve el dígito de control del número que pasas como argumento.

is_valid() es la función que comprueba si un número es válido o no.

Entonces, solo necesitas crear o generar la raíz del número, y check_digit() lo completa para hacerlo válido.

Eso es justo lo que hace el programa en Python: genera el número, de forma aleatoria, con un dígito menos, y luego genera el dígito de control y se lo pega.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-14 17:44 @780
por BigBear
Bueno, entonces mi idea es generar un número de 16 dígitos diferente constantemente en un while y después comprobar con el módulo, pero ¿me podes ayudar porque no sé usar el random en Perl? Lo sé hacer en Python, pero no en Perl.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-15 05:29 @270
por explorer
Es sencillísimo...

my $numero = join '', map { int rand 10 } 1 .. 16;

o incluso:

my $numero = int rand 1_0000_0000_0000_0000;

Bueno, en este último caso, habría que mirar si le faltan '0' delante.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-15 09:47 @449
por BigBear
Bueno, el código quedó así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!usr/bin/perl
  2.  
  3. use Algorithm::LUHN qw/check_digit is_valid/;
  4.  
  5. while (1) {
  6.     my $numero = join '', map { int rand 10 } 1 .. 16;
  7.     if ( is_valid($numero) ) {
  8.         print "[+] $numero\n";
  9.     }
  10. }
  11.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


¿ Una vez generado hay alguna forma de saber si es Visa, Mastercard u otro ?

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-15 10:55 @496
por explorer
Ese código tiene un problema: que genera más números de los que son necesarios. Quiero decir que estás eligiendo números al azar, y luego compruebas si son válidos o no. Si no lo son, lo vuelves a intentar con otro número.

Es mejor lo que hemos dicho antes: generar los primeros dígitos y luego el módulo nos extrae el último número de control (que es lo que realmente hace el programa en Python):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!usr/bin/perl
  2. use Algorithm::LUHN qw/check_digit/;
  3.  
  4. for (1..100) {
  5.     my $numero = join '', map { int rand 10 } 1 .. 15;   # generamos uno menos del largo
  6.     my $check  = check_digit($numero);                   # dígito de control
  7.     print "[+] $numero$check\n";                         # salida directa del resultado
  8. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

El saber a qué empresa pertenece, pues según la norma ISO/IEC 7812, los primeros dígitos están reservados para indicar a qué entidad se refiere el número. En el programa en Python verás que se crea un prefijo distinto según el tipo de tarjeta que queramos crear. Por ejemplo, en Visa, se elige uno de entre 8 dígitos posibles , mientras que en Amex, se elige entre dos combinaciones: '34' o '37'.

Re: Algoritmo de Luhn

NotaPublicado: 2014-01-15 12:11 @549
por BigBear
Sí, esa es la parte que no entiendo, el tema de los prefijos. Por ejemplo, si quiero generar uno con Visa tengo que cambiar el primer número por cualquiera de estos: visaPrefixList = [['4','0','2','4', '0', '0', '7', '1'],] ¿ O hay que cambiar más de dos ?