2009-04-15 10 views
5

Estoy trabajando en una aplicación donde necesito generar identificaciones únicas, no secuenciales. Una de las limitaciones que tengo es que deben constar de 3 dígitos seguidos de 2 letras (solo alrededor de 600k ID). Dado mi grupo relativamente pequeño de identificaciones, estaba considerando simplemente generar todas las identificaciones posibles, barajarlas y ponerlas en una base de datos. Dado que, internamente, tendré una identificación secuencial simple para usar, será fácil sacarlos de a uno por vez &, asegúrese de que no tenga repeticiones.¿Convertir la secuencia de números a ID de aspecto aleatorio?

Esto no se siente como una solución muy satisfactoria. ¿Hay alguien por ahí que tenga un método más interesante para generar identificaciones únicas de un grupo limitado que este método de "lotería"?

+0

¿Cuántas ID piensa utilizar realmente? Sería una pena generar tantos y almacenarlos solo para usar algunos cientos, por ejemplo. –

+0

¿por qué es importante si son secuenciales? – ninesided

Respuesta

4

Esto se puede hacer de diferentes maneras, dependiendo de lo que intente optimizar (velocidad, uso de memoria, etc.).

patrón ID = ddd c 1 c [0]

Opción 1 (esencialmente como hashing, similar a Zak de):
1 generar un número aleatorio entre 0 y el número de posibilidades (676k). número
2- Convertir a combinación

ddd = random/(26^2) 
    c[0] = random % (26) 
    c[1] = (random/26) % 26 

3- consulta de DB para la existencia de ID y el incremento hasta una libre se encuentra.

Opción 2 (Linear registro de desplazamiento de realimentación, ver wikipedia):
1- Seed con un número aleatorio en el rango (0,676k).(Véase más adelante por qué no puede sembrar con '0')
2- generar números aleatorios subsiguientes mediante la aplicación de la siguiente para el número de identificación actual

num = (num >> 1)^(-(num & 1u) & 0x90000u);

3- identificadores de salto más grandes que el rango (es decir 0xA50A0 +)
4- Convertir número en formato de ID (como se indicó anteriormente)
* Necesitará guardar el último número generado que se usó para una ID, pero no necesitará consultar la BD para ver si se usa. Esta solución enumerará todas las identificaciones posibles excepto [000 AA] debido a la forma en que funciona el LFSR.

[editar] Debido a que su alcance es en realidad más grande de lo que necesita, puede volver [000 AA] restando 1 antes de convertir a la ID y tienen sea su rango válido (0,0xA50A0]

+0

Tengo curiosidad. ¿De dónde vino ese algoritmo LFSR? –

1

Dependiendo de lo que usted define como secuencial, usted podría escoger un determinado punto de partida de las letras, como 'AA', y el bucle sólo a través de los tres dígitos, por lo que sería: 001aa 002aa 003aa

Una vez que llegue a zz, entonces incremente la parte del número.

4

Puede generar una ID aleatoria que cumpla con ese estándar, hacer una selección de DB para ver si ya existe, luego insertarla en un DB para notar que se ha "usado". Para el primer 25% de la vida de ese esquema (o aproximadamente 150k entradas), debería ser relativamente rápido generar nuevos ID aleatorios. Sin embargo, después de eso, tomará más y más tiempo, y también podría completar previamente la tabla para buscar identificaciones gratuitas.

+0

puede encapsular esto en un procedimiento almacenado que devuelve un id. No utilizado. De esta forma, no habrá repetido martillazos en la base de datos al probar el ID – ninesided

4

Usa un grupo finito. Básicamente, tome un entero de 32 o 64 bits, y encuentre un número grande que sea coprime al valor máximo para su entero; llame a este número M. Entonces, para todos los enteros n, n * M dará como resultado un número único que tiene muchos dígitos.

Esto tiene la ventaja de que no es necesario rellenar previamente la base de datos, o ejecutar una consulta de selección separada; puede hacer esto desde una declaración de inserción, haciendo que su n sea un incremento automático , y tiene una columna de identificación separada que se predetermina a n * M.

+0

, si ve dos de estos ID uno al lado del otro (o realmente 3 o más a cualquier distancia) solo podrá tomar el gcd de la ID. ya ves, y ser capaz de predecir exactamente la próxima identificación. Desafortunadamente, esta solución tendría muy poca entropía. Además, esto no se ajusta a la especificación de 3 dígitos y 2 letras que usó OP – Zak

0

Usted podría usar la aritmética modular para generar identificadores de Escoja un número que es primos entre sí, con 676.000 y de una semilla id es el incremento Identificación del nivel de la tabla a continuación, el siguiente pseudocódigo es lo que necesita:...

uidNo = (id * seed) % 676000 
digits = uidNo/676 
char1 = uidNo % 26 
char2 = (uidNo/26) % 26 
uidCode = str(digits) + chr(char1+65) + chr(char2+65) 

Si un usuario tiene más de una identificación emitida consecutivamente, pueden adivinar el algoritmo y la semilla y generar todos los identificadores en orden. significa que el algoritmo no es lo suficientemente seguro para su caso de uso.

Cuestiones relacionadas