Jump to content


Photo

Ideas para generar seriales


  • Please log in to reply
9 replies to this topic

#1 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 31 May 2012 - 05:30 PM

Me estan pidiendo que genere unas tarjetas identificadas con numeros unicos, estas tarjetas pueden llegar facilmente al millon de registros, el chiste esta que estos seriales representados en codigos de barra no se repitan.

Que solucion puedo ofrecer facil de implementar?

Nota: No importa si el codigo es code39

Saludos
  • 0

#2 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 01 June 2012 - 12:30 AM

¿Esto de aquí no te sirvió?
http://www.delphiacc...41490/#msg41490
  • 0

#3 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1092 posts
  • LocationMurcia, España

Posted 01 June 2012 - 01:02 PM

La manera "correcta" quizás sería usar checksums:

Si pones los datos de una persona todos en un txt y a ese fichero (o TMemoryStream) le sacas un hash (hash es generador de checksums, una función que dado un fichero te genera una cadena de N caracteres diferente cada vez pero el mismo siempre si le das el mismo fichero).

El algoritmo MD5 valdría, y algo mejor sería el SHA1, y mejor aun SHA2, depende de las funciones que tengas disponibles, suelen haber componentes libres que calculan el MD5 o SHA1 de un stream por el internete, yo uso SecureBlackBox pero es de pago porque hace muchísimas más cosas. Ojo que cada función devuelve una cadena más o menos larga, pero para "solo" un millón de fichas la probabilidad de que "choquen" dos códigos es despreciable en todos los casos.

Al final tendrías un código alfanumérico distinto para cada conjunto distinto de datos... un string diferente por persona, que puedes pasar a número si lo necesitas de varias formas.

Este sistema permite "validar" una tarjeta al usarse: Si su código coincide con el checksum/hash de los datos de esa persona, sabes que el código es correcto (no aleatorio) y el correcto para esa persona... eso sí, deben ser los datos usados para generar los códigos, no los datos actualizados!

Personalmente para estas cosas uso el hash SHA1, que devuelve una cadena de 10 de lago creo recordar. Estos se pueden convertir a caracteres imprimibles usando una función que los pasa a Base64 (cada byte pierde 2 bits al convertirse en imprimible, los dos últimos, pero debido a eso, la longitud es algo mayor, 40 si no me falla la lógica), todo depende de cuantos dígitos/números te quepan en el formato de código de barras que elijas.

Pero lo más sencillo en tu caso es usar un random grande (LongInt codigo:= round(random * 100000000; por ejemplo) y guardarlos en un fichero o stringlist para evitar repetir, y listo.

Si usas una base de datos tipo SQL para guardar tus datos , sería mejor ponerle en la tabla de esas personas un campo único para guardar el random como entero, y si falla la grabación es porque esta ya asignado ese número y solo tienes que generar otro y reintentar. Esto último te permitiría validar los códigos al leerlos buscándolos en la base de datos, igual que el hash pero mejor (con el hash la ventaja es no tener que guardar el código generado, por eso se usa mucho para ficheros).

Menudo rollo te he contado, me da pereza leerlo a mi mismo  :cheesy:
  • 0

#4 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 04 June 2012 - 08:21 AM

¿Esto de aquí no te sirvió?
http://www.delphiacc...41490/#msg41490


Si, y esta funcionando a la perfeccion, solo que no quiero mezclar los dos metodos.

La manera "correcta" quizás sería usar checksums:

Si pones los datos de una persona todos en un txt y a ese fichero (o TMemoryStream) le sacas un hash (hash es generador de checksums, una función que dado un fichero te genera una cadena de N caracteres diferente cada vez pero el mismo siempre si le das el mismo fichero).

El algoritmo MD5 valdría, y algo mejor sería el SHA1, y mejor aun SHA2, depende de las funciones que tengas disponibles, suelen haber componentes libres que calculan el MD5 o SHA1 de un stream por el internete, yo uso SecureBlackBox pero es de pago porque hace muchísimas más cosas. Ojo que cada función devuelve una cadena más o menos larga, pero para "solo" un millón de fichas la probabilidad de que "choquen" dos códigos es despreciable en todos los casos.

Al final tendrías un código alfanumérico distinto para cada conjunto distinto de datos... un string diferente por persona, que puedes pasar a número si lo necesitas de varias formas.

Este sistema permite "validar" una tarjeta al usarse: Si su código coincide con el checksum/hash de los datos de esa persona, sabes que el código es correcto (no aleatorio) y el correcto para esa persona... eso sí, deben ser los datos usados para generar los códigos, no los datos actualizados!

Personalmente para estas cosas uso el hash SHA1, que devuelve una cadena de 10 de lago creo recordar. Estos se pueden convertir a caracteres imprimibles usando una función que los pasa a Base64 (cada byte pierde 2 bits al convertirse en imprimible, los dos últimos, pero debido a eso, la longitud es algo mayor, 40 si no me falla la lógica), todo depende de cuantos dígitos/números te quepan en el formato de código de barras que elijas.

Pero lo más sencillo en tu caso es usar un random grande (LongInt codigo:= round(random * 100000000; por ejemplo) y guardarlos en un fichero o stringlist para evitar repetir, y listo.

Si usas una base de datos tipo SQL para guardar tus datos , sería mejor ponerle en la tabla de esas personas un campo único para guardar el random como entero, y si falla la grabación es porque esta ya asignado ese número y solo tienes que generar otro y reintentar. Esto último te permitiría validar los códigos al leerlos buscándolos en la base de datos, igual que el hash pero mejor (con el hash la ventaja es no tener que guardar el código generado, por eso se usa mucho para ficheros).

Menudo rollo te he contado, me da pereza leerlo a mi mismo  :cheesy:


Esta interesante, de hecho la parte de la clave de busueda relacionada al cliente es lo que estoy implementando, solo que la generacion queria hacerlo mas sencilla, por eso pense que podia tomar un numero pasarle una funcion y que me devolviera un codigo unico, no se en verdad si asi funciona, por ejemplo tengo el 000000001 y se convierta en 12876nd53tg3.


Solo quiero ideas, y tengo la duda que si el md5 de un valor es probable que lo tenga otro.

Saludos
  • 0

#5 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1092 posts
  • LocationMurcia, España

Posted 04 June 2012 - 09:32 AM

MD5 en pocas palabras no te va a producir colisiones (2 ficheros o en tu caso códigos que te den exactamente el mismo hash MD5).

Te comento las posibilidades "reales": MD5 produce hashes de 160 128 bits, lo que traducido a colisiones (si quieres saber más, busca por la mal llamada paradoja del cumpleaños) significa que, dado un fichero con su hash, tendrías que intentar con 2^80 2^64 ficheros diferentes para que la probabilidad de encontrar un "gemelo de hash" sea del 50%.

El problema unicamente es la dificultad que pueda representar localizarte un generador de hash en md5, y si el resultado lo puedes pasar a algún tipo de código de barras.

Peeero, de nuevo, si quieres hacer "hash" de un código que es un número entero de 8 cifras, tienes soluciones infinitamente más sencillas: Añadele un 1 al principio o al final de tu código, y obtienes un código único!

Como supongo que no quieres que nadie sepa "simular" tus tarjetas, puedes usar cualquier otro método de "liar" un texto: Cambiar de orden las letras, sumarle una cantidad a cada numero (y si pasa de 9 le restas 10), etc.

Si quieres que además sea fiable contra un "entendido" que realmente sepa lo que se hace, todo esto no te sirve, un criptografo malo te lo adivina en un ratito.. en ese caso, solo tienes funciones de hash "profesionales", y MD5 tampoco es que saque un aprobado en esto, incluso SHA1 se supone que será inseguro en 5 o 10 años... SHA256 es el mínimo que te da una seguridad "tope de gama" a 10 o 15 años vista.
  • 0

#6 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 04 June 2012 - 10:09 AM

Pues el método viene siendo el mismo de siempre:

Codigo de barras:


delphi
  1. autonumerico + hash + Digitodecontrol



El autonumerico lo pudes sacar directamente de la base de datos y el hash puedes usar el que quieras (el SHA256 lo puedes encontrar en mi pagina). El problema es la longitud de cada uno de los campos. Si usamos un EAN13 estamos limitados a 12 digitos que debemos repartir entre el autonumerico y el hash, cuanto mas espacio dejemos para el autonumerico menos fuerte sera el hash y viceversa. Por esa razón en el anterior hilo te sugerí un hash tan "básico", que te dejará sitio para el autonumerico.

Pero si no tienemos las limitaciones del EAN13, es decir podemos tener codigos largos y con letras, puedes usar SHA256 (40 caracteres alfanuméricos) como hash y reservar 10 cifras para el autonumerico. Nos quedaría un código MUY largo (50 caracteres), pero con una seguridad a prueba de bombas.

Por cierto no calcules el hash asi: Hash=SHA256(Autonumerico), hazlo asi Hash=SHA256(Autonumerico + Clavesecreta) de esta forma nadie podrá calcular el hash sin saber la clave secreta.

En resumen, lo mismo de antes pero con mas dígitos  :cheesy:


  • 0

#7 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 05 June 2012 - 08:07 AM

Gracias a los dos, esta semana hago las pruebas y subo los resultados-  (y)
  • 0

#8 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 18 June 2012 - 12:06 PM

Bueno probe con el sha256, pero me quede con el codigo anterior cambiando solamente la semilla, gracias Domingo y Sergio
  • 0

#9 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 18 June 2012 - 03:31 PM

Bueno probe con el sha256, pero me quede con el codigo anterior cambiando solamente la semilla, gracias Domingo y Sergio


Era un buen código  (h)  :D
  • 0

#10 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4483 posts
  • LocationVenezuela

Posted 19 June 2012 - 08:23 AM


Bueno probe con el sha256, pero me quede con el codigo anterior cambiando solamente la semilla, gracias Domingo y Sergio


Era un buen código  (h)  :D


La verdad si es, te quedo perfecto, lo que pasa es que no recordaba que con cambiar la semilla tenia un formato distinto.  Ya la memoria me esta jugando estas malas pasadas
  • 0




IP.Board spam blocked by CleanTalk.