2009-05-21 13 views
15

Sto lavorando a un sistema di biglietteria online per eventi, in cui gli utenti potranno stampare i propri biglietti e presentarsi all'evento dove che verrà sottoposto a scansione (codice a barre) e, idealmente, la persona si metterà in il mio problema è come creare un "codice biglietto" che soddisfi i seguenti requisiti:.Idee per creare un hash piccolo (<10 cifre), non (molto) sicuro "

  • ogni "codice del biglietto" devono essere sufficientemente diverso da ogni altro (cioè non numerato sequenzialmente)
  • idealmente il biglietto verrà controllato rispetto a un DB centrale per evitare il riutilizzo, ma è necessario poter lavorare anche fuori linea, nel qual caso il sistema deve controllare un biglietto "valido" codice e che non ha stato utilizzato in questo gate.
  • il "codice biglietto" deve essere abbastanza piccolo per facilitare il keying, se necessario
  • il possessore del biglietto avrebbe solo bisogno il biglietto per entrare in (cioè nessun controllo ID)

La gamma dei dati è molto piccolo, ci saranno solo circa 20 eventi in 4 giorni con circa 5.000 biglietti per evento (circa 100.000 codici di biglietti diversi)

Ora ho diversi campi che non sono stampati sul biglietto e non noti all'utente che Posso usare per codificare parte del "codice ticket", quindi potrei usare EventId, OrderId, EventDate e alcuni salt per creare un piccolo "hash" per pa rt del codice (idee?), ma sono ancora bloccato con l'ID del ticket che è sequenziale o un GUID (sarebbe troppo lungo)

Quindi qualsiasi idea o puntatore su come farlo?

+0

@jaimedp leggi il mio aggiornamento – Unknown

+1

Che ne dici di un normale algoritmo di hashing, ma con un hash troncato? –

risposta

1

Si consideri uno schema molto semplice basato su una rete Feistel per permutare, ad esempio, il numero ID del biglietto. This message (che si trova nelle liste PostgreSQL ma che in realtà non ha molto a che fare con PostgreSQL) descrive un semplice Feistel network. Su ogni biglietto è possibile stampare un numero identificativo del biglietto (scelto in sequenza), quindi un "codice segreto del biglietto" che è il risultato del posizionamento del numero ID attraverso una rete Feistel.Le possibili variazioni includono l'aggiunta di una cifra di controllo al codice segreto e l'immissione dell'input sulla rete Feistel su più del solo numero generato sequenzialmente (numero + 10.000 * numero identificativo dell'evento, eccetera).

+0

Grazie, questo mi ha indirizzato nella giusta direzione combinata con una cifra di controllo di Verhoeff e un hash di ciò che posso ricostruire. – Jaime

3

due modi posso vedere:

  1. generare un numero casuale, o almeno una parte casuale per un numero e conservarlo in un database centrale. Quindi scaricare il database in tutti i sistemi di gate da controllare.
  2. Il numero deve essere autosufficiente. In altre parole, il numero deve essere in grado di effettuare il check out senza l'elenco salvato. Sembra una specie di sistema di checksum. Ad esempio, è possibile emettere numeri da 1 in su, renderli 5 cifre (00000-99999 = 100.000 numeri) e prependere 1-3 lettere, assicurandosi di finire con un checksum da verificare.
+0

Il problema con no. 1 è che devo essere in grado di lavorare fuori linea, e un biglietto avrebbe potuto essere acquistato online solo pochi minuti prima, quindi non avrei mai potuto avere una versione aggiornata del ticket db. Ora, come per il n. 2, come faresti un codice biglietto sufficientemente diverso dal precedente? – Jaime

0

Per la verifica in linea, vedo solo una soluzione facile ..

Allega al ID biglietti per un hash del ID biglietti e sale per-evento. Puoi troncare qualsiasi hash crittografico alla dimensione desiderata. Non riesco a pensare a una ragione particolare per utilizzare qualsiasi cosa tranne un numero casuale per l'ID del ticket di base.

Ciò consente di limitare le dimensioni dell'ID ticket e di avere una sicurezza chiaramente proporzionale in relazione alla dimensione dell'ID ticket.

+0

Questo è quello che sto pensando anch'io, ma quanto è valido (in termini di variabilità e numero di hash) usare solo una parte di say hash MD5? – Jaime

+0

Se si tratta di un hash crittograficamente sicuro (anche scontando il fatto che MD5 è stato interrotto), l'utilizzo di una parte dell'hash dovrebbe fornire la diminuzione prevista/proporzionale della variabilità e del numero di hash. Ad esempio, per ridurre la dimensione dell'hash da 128 bit a 32 bit (indipendentemente dai 32 bit che si scelgono), si riduce il numero di possibili hash da 2^128 a 2^32. Anche la complessità di un attacco a forza bruta o la probabilità di una collisione accidentale sono proporzionalmente più facili. – chuck

0

È possibile eseguire un calcolo CRC.

Fondamentalmente, basta iniziare ad aggiungere ogni carattere nella stringa e limitare la lunghezza a un intero lungo.

È possibile iniziare con un numero casuale noto e memorizzarlo nei primi 4 byte e fare in modo che gli ultimi quattro siano un calcolo come descritto in precedenza.

Questo sarebbe due ints o otto byte.

0

Ecco uno schema che ha il vantaggio di lasciare che si calcola l'hash biglietto successivo dal precedente (in modo da poter verificare se ne manca uno), ma non si lascia estranei calcolano la prossima:

Ticket.0 = substring(HASH(SALT + IV  ), 0, LENGTH) 
Ticket.i = substring(HASH(SALT + Ticket.i-1), 0, LENGTH) 

dove

  • HASH è alcuna funzione di hashing che distribuisce la sua entropia relativamente modo uniforme su tutta la stringa di uscita
  • SALT è una costante si mantiene secre t; è una buona idea di utilizzare una diversa per ogni evento
  • IV è un'altra costante che si tengono segreto
  • lunghezza è la lunghezza della ID biglietto che si desidera (10 nella sua interrogazione, ma 12 non è fuori questione e ti dà 256 volte più ID biglietto)
+0

Che non può essere verificato se il computer non funziona. O stai suggerendo che i computer sulla porta calcolino il numero del biglietto da zero? – jmucchiello

+0

Il problema che vedo è che il computer alla porta non può verificare se un dato ticket è valido, poiché non ha tutto il ticket localmente. O mi sta sfuggendo qualcosa? – Jaime

+0

Suppongo che qualsiasi soluzione debba avere una copia locale del database di tutti i ticket generati. Il vantaggio di questa soluzione è che puoi generare il database offline dalla 4-tupla . E se numberOfTicketsSold cambia (b/c qualcuno ne compra uno online 7 minuti prima dello spettacolo), è facile aggiungere altri valori al database. Eppure i valori sono difficili da calcolare senza la 4-tupla. –

11

Perché reinventare la ruota? Basta fare qualcosa di simile (codice Python, mi chiede se avete bisogno di chiarimenti):

import hashlib 

secretpassword = "blah" 

def createticket(eventnum, ticketnum): 
    m = hashlib.md5() # or any crypto hash you like 
    m.update("%s%s%s" % (eventnum, ticketnum, secretpassword)) 
    return m.hexdigest()[:10] 

Esempio:

Numero Evento 1

biglietteria Numero 123

createticket(1,123) 
# output: 2d7f242597 

Mr ticketman viene con il suo verificatore ed entra nel numero di evento/biglietto e nell'hash:

def verifier(eventnum, ticketnum, hash): 
    return hash == createticket(eventnum, ticketnum) 

verifier(1,123, "2d7f242597") 
# ouput: True 
+0

Forse non ho capito bene, ma il mio problema con un hash completo (ala md5) è che non ho il numero del biglietto per la verifica, quindi non posso creare un hash da verificare. Questa potrebbe essere una domanda diversa, quanto è valido utilizzare solo le prime x cifre dell'hash? – Jaime

+4

@jaimedp, ecco perché quando stampi il biglietto, includi il numero dell'evento e il numero del biglietto insieme all'hash. È completamente valido utilizzare le prime x cifre dell'hash perché tutti gli hash crittografici validi devono distribuire l'entropia a tutte le cifre (effetto valanga). – Unknown

+0

@jaimedp, anche quando si stampa il codice a barre, basta codificare il numero dell'evento e il numero del biglietto come le prime poche posizioni. Non c'è motivo per te di non avere le informazioni. In effetti, questa soluzione è praticamente uguale a quella che hai accettato, tranne che devi lasciarti andare con il tuo codice a blocchi. – Unknown