random - identificador - uuid npm
¿Cómo puedo crear un código único de 7 dígitos para una entidad? (11)
Cuando un usuario agrega un nuevo elemento en mi sistema, quiero producir un código seudoaleatorio de 7 dígitos para ese elemento. La cantidad de elementos creados solo se contará en miles (<10,000).
Debido a que necesita ser único y no hay dos elementos que tengan la misma información, podría usar un hash, pero debe ser un código que puedan compartir con otras personas, de ahí los 7 dígitos.
Mi idea original era simplemente repetir la generación de un número aleatorio, verificar que no estuviera ya usado, y si lo fuera, enjuagar y repetir. Creo que esta es una solución razonable aunque desagradable dada la baja probabilidad de colisiones.
Las respuestas a esta pregunta sugieren generar una lista de todos los números no utilizados y mezclarlos. Probablemente podría mantener una lista como esta en una base de datos, pero estamos hablando de 10,000,000 entradas por algo relativamente infrecuente.
¿Alguien tiene una mejor manera?
Bien, podrías pedirle al usuario que elija su propio número de 7 dígitos y validarlo contra la población de números existentes (que habrás almacenado a medida que se agotaron), pero sospecho que estarías filtrando un montón de 1234567, 7654321 , 9999999, 7777777 escribe respuestas y puede que necesites algunos RegEx para lograr el filtrado, además deberías advertir al usuario contra tales secuencias para no tener una experiencia de usuario negativa, repetitiva.
Con solo miles de elementos en la base de datos, su idea original parece sólida. Verificar la existencia de un valor en una lista ordenada (indexada) de unas pocas decenas de miles de elementos solo requeriría algunas búsquedas y comparaciones de datos.
La generación previa de la lista no parece una buena idea, ya que almacenará muchos más números de los necesarios, o tendrá que lidiar con quedarse sin ellos.
Elija un número primo A de 7 dígitos, y un número primo grande B , y
int nth_unique_7_digit_code(int n) {
return (n * B) % A;
}
El conteo de todos los códigos únicos generados por esto será A.
Si quieres ser más "seguro", haz pow(some_prime_number, n) % A
, es decir,
static int current_code = B;
int get_next_unique_code() {
current_code = (B * current_code) % A;
return current_code;
}
Honestamente, si quieres generar solo un par de miles de códigos de 7 dígitos, mientras 10 millones de códigos diferentes estarán disponibles, creo que generar uno aleatorio y verificar que la colisión sea lo suficientemente buena.
La probabilidad de una colisión en el primer golpe será, en el peor de los casos, de aproximadamente 1 en mil, y el esfuerzo computacional para generar un nuevo código de 7 dígitos y verificar una colisión nuevamente será mucho más pequeño que mantener un diccionario, o soluciones similares.
Usar un GUID en lugar de un código de 7 dígitos como sugerencias sugeridas también funcionará, pero por supuesto un GUID será un poco más difícil de recordar para los usuarios.
Intentaría usar un LFSR (registro de desplazamiento de retroalimentación lineal), el código es realmente simple, puedes encontrar ejemplos en todas partes, es decir, Wikipedia, y aunque no es criptográficamente seguro, parece muy aleatorio. Además, la implementación será muy rápida ya que usa principalmente operaciones de cambio.
La probabilidad de tener aciertos es muy baja.
Por ejemplo, tiene 10 ^ 4 usuarios y 10 ^ 7 ID posibles.
La probabilidad de que elija ID utilizada 10 veces seguidas ahora es 10 ^ -30.
Esta posibilidad es menor que una vez en la vida de cualquier persona.
Puede usar un ID de incremento y luego XOR en alguna clave fija.
const int XORCode = 12345;
private int Encode(int id)
{
return id^XORCode;
}
private int Decode(int code)
{
return code^XORCode;
}
Sugeriría usar un guid en lugar de un código de 7 dígitos, ya que será más único y no tendrá que preocuparse por generarlos, ya que .NET hará esto por usted.
Supongo que tendrás una tabla de los generados . En ese caso, no veo un problema para elegir números aleatorios y compararlos con la base de datos, pero no lo haría individualmente. Generarlos es barato, hacer la consulta DB es costoso en relación con eso. Generaría 100 o 1,000 a la vez y luego preguntaría al DB cuál de esos existe. Apuesto a que no tendrás que hacerlo dos veces la mayor parte del tiempo.
Tienes <10.000 elementos, por lo que solo necesitas 4 dígitos para almacenar un número único para todos los artículos. Como tiene 7 dígitos, tiene 3 dígitos adicionales.
Si combina un número de secuencia único de 4 dígitos con un número aleatorio de 3 dígitos, será único y aleatorio. Incrementa el número de secuencia con cada ID nueva que genera.
Puede agregarlos en cualquier orden o mezclarlos.
seq = abcd, rnd = ABC
Puede crear los siguientes ID''s:
- abcdABC
- ABCabcd
- aAbBcCd
Si usa solo un algoritmo de mezcla, tendrá números únicos, que se ven al azar.
Todas las soluciones para una ID "única" deben tener una base de datos en alguna parte: una que contenga las ID utilizadas o una con las ID gratuitas. Como ha notado, la base de datos con identificaciones gratuitas será bastante grande, por lo que la mayoría de las personas utilizan una base de datos de "identificaciones usadas" y comprueban colisiones.
Dicho esto, algunas bases de datos ofrecen un generador / secuencia de "identificación aleatoria" que ya devuelve los ID en un rango en orden aleatorio.
Esto funciona mediante el uso de un generador de números aleatorios que puede crear todos los números en un rango sin repetirse más la función de que puede guardar su estado en alguna parte. Entonces, lo que debes hacer es ejecutar el generador una vez, usar la ID y guardar el nuevo estado. Para la próxima ejecución, carga el estado y restablece el generador al último estado para obtener la siguiente identificación aleatoria.