2009-04-15 5 views
5

Sto lavorando a un'applicazione in cui è necessario generare ID univoci e non sequenziali. Uno dei limiti che ho è che devono essere composti da 3 cifre seguite da 2 lettere (solo circa 600k ID). Dato il mio pool relativamente piccolo di ID, stavo considerando semplicemente la generazione di tutti gli ID possibili, mescolandoli e inserendoli in un database. Dal momento che, internamente, avrò un ID semplice e sequenziale da utilizzare, sarà facile estrarli uno alla volta, & assicurati che non abbia alcuna ripetizione.Convertire la sequenza di numeri in ID dall'aspetto casuale?

Questo non sembra una soluzione molto soddisfacente. Qualcuno là fuori ha un metodo più interessante di generazione di ID univoci da un pool limitato rispetto al metodo "lotteria"?

+0

Quanti ID hai intenzione di utilizzare? Sarebbe un peccato generare così tanti e conservarli solo per usarne alcune centinaia. –

+0

perché è importante se sono sequenziali? – ninesided

risposta

4

Questo può essere fatto in molti modi diversi, a seconda di cosa si sta cercando di ottimizzare (velocità, utilizzo della memoria, ecc.).

pattern ID = ddd c 1 c [0]

Opzione 1 (essenzialmente come hashing, simile a Zak):
1 generare un numero casuale compreso tra 0 e il numero di possibilità (676k). numero
2- Converti in combinazione

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

3- Query DB per l'esistenza di ID e l'incremento fino a quando uno libero viene trovato.

Opzione 2 (Linear registro a scorrimento a retroazione, vedi wikipedia):
1- Seed con un numero casuale nell'intervallo (0,676k).(Vedi sotto cui non si può seminare con '0')
2- Genera numeri casuali successivi applicando quanto segue per il numero di ID corrente

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

3- Vai ID più grandi di gamma (cioè 0xA50A0 +)
4- Convertire il numero nel formato ID (come sopra)
* È necessario salvare l'ultimo numero generato utilizzato per un ID, ma non è necessario interrogare il DB per verificare se viene utilizzato. Questa soluzione enumera tutti gli ID possibili tranne [000 AA] a causa del modo in cui funziona l'LFSR.

[modifica] Dal momento che il range è in realtà più grande del necessario, si può tornare indietro [000 AA] sottraendo 1 prima di convertire l'ID e la tua intervallo valido sia (0,0xA50A0]

+0

Sono curioso. Da dove viene l'algoritmo LFSR? –

1

seconda di ciò che si definisce come sequenziale, si può solo scegliere un certo punto di partenza sulle lettere, come ad esempio 'AA', e basta scorrere le tre cifre, in modo da sarebbe: 001aa 002aa 003aa

Una volta arrivato a zz, incrementare la parte del numero.

4

È possibile generare un ID casuale conforme a tale standard, fare un DB selezionare per vedere se esiste già, quindi inserirlo in un DB per notare che è stato "utilizzato". Per il primo 25% della vita di tale schema (o circa 150k voci), dovrebbe essere relativamente veloce generare nuovi ID casuali. Dopodiché, ci vorranno sempre più tempo e potresti anche pre-riempire la tabella per cercare gli ID gratuiti.

+0

è possibile incapsulare questo in una stored procedure che ha restituito un ID non utilizzato. In questo modo non stai martellando ripetutamente il database durante il test dell'ID – ninesided

4

Utilizzare un gruppo finito. Fondamentalmente, prendi un numero intero a 32 o 64 bit e trova un numero grande che è coprimi al valore massimo per il tuo intero; chiama questo numero M. Quindi, per tutti gli interi n, n * M si otterrà un numero univoco con molte cifre.

Questo ha il vantaggio che non è necessario precompilare il database o eseguire una query di selezione separata: è possibile eseguire tutto da un'unica istruzione di inserimento, avendo il proprio n solo un incremento automatico. e dispone di una colonna ID separata predefinita per n * M.

+0

, se vedi due di questi ID affiancati (o in realtà 3 o più a qualsiasi distanza) sarai solo in grado di prendere il gcd dell'ID vedi, ed essere in grado di prevedere esattamente il prossimo ID. Sfortunatamente, questa soluzione avrebbe pochissima entropia. Inoltre, questo non è conforme alle 3 cifre, 2 lettere spec l'OP usato – Zak

0

È potrebbe usare l'aritmetica modulare per generare ids scegliere un numero che è coprimi con 676.000 e per un seme id è lo standard incrementare id della tabella Poi il seguente pseudocodice è quello che ti serve:...

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

Se un utente ha più di un ID emesso consecutivamente, potrebbero indovinare l'algoritmo e il seed e generare tutti gli id ​​in ordine. significa che l'algoritmo non è abbastanza sicuro per il tuo caso d'uso.