Domanda

Sto lavorando a un'applicazione in cui gli utenti devono effettuare una chiamata e digitare un numero di verifica con la tastiera del proprio telefono.

Vorrei essere in grado di rilevare se il numero digitato è corretto o meno.Il sistema telefonico non ha accesso a un elenco di numeri validi, ma convaliderà invece il numero rispetto a un algoritmo (come il numero di una carta di credito).

Ecco alcuni dei requisiti:

  • Deve essere difficile digitare un codice casuale valido
  • Deve essere difficile avere un codice valido se faccio un errore di battitura (trasposizione di cifre, cifra sbagliata)
  • Devo avere un numero ragionevole di combinazioni possibili (diciamo 1M)
  • Il codice deve essere il più breve possibile, per evitare errori da parte dell'utente

Dati questi requisiti, come genereresti un numero del genere?

MODIFICARE :

@Haaked:Il codice deve essere numerico perché l'utente lo digita con il proprio telefono.

@mattb:Nel primo passaggio il codice viene visualizzato su una pagina Web, il secondo passaggio consiste nel chiamare e digitare il codice.Non conosco il numero di telefono dell'utente.

Seguito :Ho trovato diversi algoritmi per controllo la validità dei numeri (vedi questo interessante progetto Google Code: checkDigits).

È stato utile?

Soluzione

Dopo alcune ricerche, penso che andrò con il ISO 7064 Mod. 97,10 formula.Sembra piuttosto solido in quanto viene utilizzato per convalidare l'IBAN (numero di conto bancario internazionale).

La formula è molto semplice:

  1. Prendi un numero: 123456
  2. Applicare la seguente formula per ottenere il checksum di 2 cifre: mod(98 - mod(number * 100, 97), 97) => 76
  3. Concat numero e checksum per ottenere il codice => 12345676
  4. Per convalidare un codice, verificalo mod(code, 97) == 1

Test :

  • mod(12345676, 97) = 1 => BUONO
  • mod(21345676, 97) = 50 => MALE!
  • mod(12345678, 97) = 10 => MALE!

Apparentemente, questo algoritmo rileva la maggior parte degli errori.

Un'altra opzione interessante era il Algoritmo di Verhoeff.Ha una sola cifra di verifica ed è più difficile da implementare (rispetto alla semplice formula sopra).

Altri suggerimenti

Per le combinazioni da 1 milione avrai bisogno di 6 cifre.Per essere sicuri che non ci siano codici validi accidentalmente, suggerisco 9 cifre con una probabilità 1/1000 che un codice casuale funzioni.Suggerirei anche di utilizzare un'altra cifra (10 in totale) per eseguire un controllo dell'integrità.Per quanto riguarda i modelli di distribuzione, sarà sufficiente quello casuale e la cifra di controllo garantirà che un singolo errore non dia luogo a un codice corretto.

Modificare: A quanto pare non ho letto completamente la tua richiesta.Utilizzando un numero di carta di credito, puoi eseguire un hash su di esso (MD5 o SHA1 o qualcosa di simile).Quindi troncare in un punto appropriato (ad esempio 9 caratteri) e convertire in base 10.Quindi aggiungi le cifre di controllo e questo dovrebbe più o meno funzionare per i tuoi scopi.

Vuoi segmentare il tuo codice.Parte di esso dovrebbe essere un CRC a 16 bit del resto del codice.

Se tutto ciò che desideri è un numero di verifica, utilizza semplicemente un numero di sequenza (supponendo che tu abbia un singolo punto di generazione).In questo modo sai che non riceverai duplicati.

Quindi aggiungi un prefisso alla sequenza con un CRC-16 di quel numero di sequenza E una chiave privata.Puoi utilizzare qualsiasi cosa per la chiave privata, purché la mantieni privata.Rendilo qualcosa di grande, almeno a GUIDA, ma potrebbe essere il testo a Guerra e pace dal progetto Gutenberg.Deve solo essere segreto e costante.Avere una chiave privata impedisce alle persone di falsificare una chiave, ma l'utilizzo di un CR a 16 bit ne facilita la violazione.

Per convalidare basta dividere il numero nelle sue due parti, quindi prendere un CRC-16 del numero progressivo e della chiave privata.

Se vuoi oscurare maggiormente la parte sequenziale, dividi il CRC in due parti.Metti 3 cifre all'inizio e 2 alla fine della sequenza (tasto zero in modo che la lunghezza del CRC sia coerente).

Questo metodo ti consente di iniziare anche con tasti più piccoli.Le prime 10 chiavi saranno di 6 cifre.

Devono essere solo numeri?Potresti creare un numero casuale compreso tra 1 e 1 milione (suggerirei comunque anche più alto) e poi Base32 lo codifica.La prossima cosa che devi fare è eseguire l'hash di quel valore (utilizzando un valore salt segreto) e codificare base32 l'hash.Quindi unisci le due stringhe insieme, magari separate dal trattino.

In questo modo, puoi verificare algoritmicamente il codice in entrata.Prendi semplicemente il lato sinistro del codice, esegui l'hashing utilizzando il tuo sale segreto e confronta quel valore con il lato destro del codice.

  • Devo avere un numero ragionevole di combinazioni possibili (diciamo 1M)
  • Il codice deve essere il più breve possibile, per evitare errori da parte dell'utente

Bene, se vuoi che abbia almeno un milione di combinazioni, allora hai bisogno di almeno sei cifre.È abbastanza corto?

Quando crei il codice di verifica, hai accesso al numero di telefono del chiamante?

In tal caso, utilizzerei il numero di telefono del chiamante e lo eseguirei tramite una sorta di funzione di hashing in modo da poter garantire che il codice di verifica fornito al chiamante nel passaggio 1 sia lo stesso che sta inserendo nel passaggio 2 (per essere sicuro non stanno utilizzando il codice di convalida di un amico o hanno semplicemente fatto un'ipotesi molto fortunata).

Per quanto riguarda l'hashing, non sono sicuro che sia possibile prendere un numero di 10 cifre e ottenere un risultato hash che sarebbe <10 cifre (immagino che dovresti convivere con una certa quantità di collisioni) ma penso ciò contribuirebbe a garantire che l'utente sia chi dice di essere.

Ovviamente questo non funzionerà se il numero di telefono utilizzato nel passaggio 1 è diverso da quello da cui chiamano nel passaggio 2.

Supponendo che tu sappia già come rilevare quale tasto ha premuto l'utente, questo dovrebbe essere fattibile abbastanza facilmente.Nel mondo della sicurezza esiste il concetto di password "una tantum".Questo a volte viene definito "password usa e getta". Normalmente questi sono limitati ai valori ASCII (facilmente digitabili).Quindi, [a-zA-z0-9] e un mucchio di simboli facilmente digitabili.come virgola, punto, punto e virgola e parentesi.Nel tuo caso, però, probabilmente vorrai limitare l'intervallo a [0-9] ed eventualmente includere * e #.

Non sono in grado di spiegare adeguatamente tutti i dettagli tecnici di come questi codici monouso vengono generati (o funzionano).C'è qualche calcolo intermedio dietro, che macellerei senza prima rivederlo io stesso.Basti dire che usi un algoritmo per generare un flusso di password monouso.Non importa quanti codici precedenti conosci, quello successivo dovrebbe essere impossibile da indovinare!Nel tuo caso, utilizzerai semplicemente ciascuna password nell'elenco come codice casuale dell'utente.

Piuttosto che non riuscire a spiegare personalmente i dettagli dell'implementazione, ti indirizzerò a un articolo di 9 pagine in cui potrai documentarti tu stesso: https://www.grc.com/ppp.htm

Sembra che tu abbia l'esigenza inespressa di dover determinare rapidamente, tramite un algoritmo, che il codice è valido.Ciò escluderebbe che tu debba semplicemente distribuire un elenco di numeri di un time pad.

Ci sono diversi modi in cui le persone lo hanno fatto in passato.

  1. Crea una chiave pubblica e una chiave privata.Codifica i numeri da 0 a 999.999 utilizzando la chiave privata e distribuisci i risultati.Dovrai inserire alcuni numeri casuali per far sì che il risultato arrivi alla versione più lunga e dovrai convertire il risultato dalla base 64 alla base 10.Quando inserisci un numero, riconvertilo in base64, applica la chiave privata e verifica se i numeri interessanti sono inferiori a 1.000.000 (scarta i numeri casuali).
  2. Usare un funzione hash reversibile
  3. Utilizza il primo milione di numeri di un PRN con valore specifico.La funzione di "controllo" può ottenere il seme e sapere che il prossimo milione di valori sono buoni.Può generarli ogni volta e controllarli uno per uno quando viene ricevuto un codice, oppure all'avvio del programma memorizzarli tutti in una tabella, ordinati e quindi utilizzare la ricerca binaria (massimo di confronti) poiché un milione di numeri interi non è molto di spazio.

Esistono molte altre opzioni, ma queste sono comuni e facili da implementare.

-Adamo

Ti sei collegato a controllare le cifre project e l'utilizzo della funzione "codifica" sembra una buona soluzione.Dice:

encode può generare un'eccezione se dati "errati" (ad es.non numerico) gli viene passato, mentre la verifica restituisce solo vero o falso.L'idea qui è che encode normalmente ottiene i suoi dati da fonti interne "attendibili" (una chiave di database per esempio), quindi dovrebbe essere abbastanza normale, anzi eccezionale, che vengano trasmessi dati errati.

Quindi sembra che potresti passare alla funzione di codifica una chiave del database (5 cifre, ad esempio) e potresti ottenere un numero che soddisfi le tue esigenze.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top