8

Considerando quanto segue:Quale sarebbe uno schema di ID ordine valido per una soluzione di e-commerce o un servizio web a pagamento?

a) si desidera un po 'di riservatezza (come nel non dire a tutti quanti ordini avete ricevuto).

b) si desidera una cifra di controllo (ad esempio, utilizzando l'algoritmo di Verhoeff) alla fine in modo da poter facilmente dire errori di ortografia e aiutare a gestire gli errori durante la scansione dei codici a barre, se questo è il caso.

c) è necessario considerare il tempo in modo che i consumatori possano ordinare l'ordine degli ordini.

d) dovrebbe essere tutto numerico o hexdec, ecc. ?.

e) qualcosa che il consumatore può dire al telefono al team di supporto ed è sufficiente per identificare l'ordine senza che il personale debba chiedere e-mail, ecc., A causa di problemi di sicurezza.

Mi piacerebbe sentire alcune opinioni.

PS: qualsiasi algoritmo progettato per risolvere questo problema sarebbe anche considerato una risposta valida per me.

+0

"un PHP o MySQL pezzo di codice progettato per risolvere questo problema sarebbe considerato una valida risposta per me" - è che un altro modo di dire "pls sendz teh codez "? –

+0

No, ma se c'è qualcuno là fuori che ha fatto un algoritmo che risolve questo mi piacerebbe molto. Ho modificato il testo per evitare che qualcun altro pensi male alle mie intenzioni. –

risposta

1

Che ne dici di una stringa casuale di qualsiasi lunghezza tu ritenga opportuno? Usa caratteri che non sono facilmente confusi con altri personaggi per la lettura al telefono. Quindi, per ogni ordine di chiamata qualcosa come:

public static string GetRandomString(int length) 
    { 
     char[] chars = "ACDEFGHJKMNPQRTWXY34679".ToCharArray(); 
     var crypto = new RNGCryptoServiceProvider(); 
     var data = new byte[length]; 
     crypto.GetNonZeroBytes(data); 
     var result = new StringBuilder(length); 
     for (int i = 0; i < data.Length; i++) 
     { 
      result.Append(chars[data[i] % chars.Length]); 
     } 

     return result.ToString(); 
    } 

Indovinare 8 caratteri restituiti dal metodo di cui sopra è una possibilità 1/282429536481. E manterrai l'integrità nel db con un vincolo unico vero?

+0

che dire di "ordinare l'ordine degli ordini"? – Kevin

+0

Immagino che tu abbia un campo OrderDate giusto? – JeremyWeir

0

È possibile utilizzare uno GUID. Per ridurlo a una stringa amichevole del cliente, varrebbe la pena eseguire il valore tramite un convertitore Base32 che risulterebbe in una stringa contenente 26 caratteri di AZ e cifre 2-7

Per soddisfare gli altri criteri, è possibile aggiungere un controllare la cifra sul valore guida e probabilmente nel database occorrerà un numero di ordine incrementale genuino separato per garantire l'univocità e consentire l'indicizzazione/l'ordinamento naturale.

+0

è necessario solo i primi caratteri del GUID per limitare realmente la voce effettiva, osservare come Git richiede solo i primi 4 - 5 caratteri per identificare in modo univoco un commit. basta chiedere ai clienti qualche altro personaggio fino a quando non si ottiene una corrispondenza con il loro nome. –

5

Ecco la mia soluzione.

Hanno tre parti x-y-z dove x è il timestamp, y il codice casuale ez è la cifra di controllo prodotta dalla concatenazione di xe y. Ma per semplificare (renderlo più piccolo), xey sono dati in una base personalizzata, invece di base numerica 10, ma z viene comunque fornito alla base 10.

Esempi di ID si possono ottenere con questo approccio:

  • LP9NTX-8D41-QW6R-9
  • LP9NTY-5H3L-BFS7-5
  • LP9NTZ-RWL3-D619-8
  • LP9NVB-BW74-788W-6
  • LP9NVW-G17D-4911- 8

Quindi è possibile ordinare in base al timestamp (notare come va in un ordine alfanumerico incrementale, se non si conosce esattamente quale sia una base numerica).

Per questo ho usato le cifre + lettere maiuscole di base58 (alla fine non importa se ho usato lettere minuscole o superiori), che è base62 senza alcuni caratteri confusi. Flickr, bit.ly and others use base58 for making Twitter 'friendly' links and the like.

Il Verhoeff :: calcsum in basso è Verhoeff’s Dihedral Group D5 Check by Dahnielson. L'unico montaggio che ho apportato è stato inserire il suo codice in una classe, quindi è lo stesso.

Ecco il codice: (* un po 'modificato da quello che ho promesso le linee up there ^)

<?php 
    $time_divisor = 3; 
    $base = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";//consider using another base **see note below** 
    $lower_limit = 50000;//just to avoiding to confuse the user with a lower number 
    $upper_limit = 1291467968;//1291467968 == ZZZZZZ in this base I used 
    //you can check the limit with base_decode("ZZZZZZ", $base); 
    $ptime = (int)($_SERVER['REQUEST_TIME']/$time_divisor);//or time(); 
    $rand1 = mt_rand($lower_limit, $upper_limi); 
    $rand2 = mt_rand($lower_limit, $upper_limi); 
    $ptime_b = base_encode($time, $base); 
    $rand1_b = base_encode($rand1, $base); 
    $rand2_b = base_encode($rand2, $base); 

    $order_id = $ptime_b.$rand1_b.$rand2_b.Verhoeff::calcsum($time.$rand1.$rand2); 
    echo $order_id; 
?> 

Subito dopo ho finito di scrivere questo altro, eventualmente, di cose che vanno male è venuto in mente. Mi sono ricordato che non vuoi che i tuoi consumatori si sentano insultati. Quindi anche le pessime parole come 'f? Ck' o '4ss' alla fine appaiono forse ok (e quasi certamente lo faranno), le parole esplicite (come nel cambiare il '4' per 'a' nella parola precedente) non sono sicuramente . A causa di questo vi consiglio di usare la seguente base alternativo/UPPER_LIMIT invece:

<?php 
    $lower_limit = 27000;//=2111 
    $upper_limit = 809999;//=ZZZZ 
    $base = "123456789BCDFGHJKLMNPQRSTVWXYZ";//erased -a -e -u 
?> 

Si prega di notare che se si tenta di utilizzare i numeri più grandi si arriva limite int superiore di PHP, così come il limite mt_rand, che può essere visto con mt_getrandmax(). Inoltre, vorrei dire che per quello che vedo l'entropia di mt_rand è sufficiente.

Se avete bisogno di numeri più grandi per la parte casuale, vi consiglio di aggiungere una terza parte a qualcosa con qualcosa come mt_rand (i, j); dove i e j sono i valori minimo e massimo per la tua base che aumenteranno il tuo ID ordine in lunghezza $ num-chars (in realtà ho fatto questo, w/la configurazione di cui sopra).

E sul lato DB è un campo unico per evitare collisioni.

Grazie a tutti.

1

java.util.UUID.randomUUID()

Problemi correlati