Domanda:
Stringa di identificazione sequenziale che non può essere decodificata (il problema del "numero di fattura")
Escher
2015-12-13 22:07:45 UTC
view on stackexchange narkive permalink

Supponiamo che gestisca un sito Web in cui è possibile creare immagini di gatti. Assegno a ogni immagine di gatto un identificatore univoco in modo che possa essere condivisa sui social media con http://catpictures.com/base62Identifier.

Potrei dare alle immagini di gatto identificatori sequenziali come 1,2,3, ecc., ma poi sarebbe possibile scoprire facilmente quante nuove immagini di gatti gli utenti creano al giorno (tramite l'identificatore più grande che restituisce HTTP 200 ogni giorno). Questo mi espone alla strategia comune di ordinare un prodotto dai tuoi concorrenti una volta al mese e annotare il numero di fattura. I dati sul traffico del sito web sono ben correlati alle entrate aziendali, quindi ovviamente desidero mantenere segrete queste informazioni.

Quello che sto pensando di provare:

Sembra un lavoro per un algoritmo di hashing , giusto? Il problema è che osservando un hash è abbastanza facile dire quale algoritmo lo ha creato (md5, crc32, ecc.). Qualcuno con un tavolo arcobaleno farebbe un breve lavoro su quell'idea. Potrei salare l'identificatore [hash ("salt" +1), hash ("salt" +2), ...], ma poi dovrei preoccuparmi della sicurezza associata al salt. E il controllo delle collisioni.

Un'altra idea che ho avuto era quella di generare una stringa casuale di caratteri e usarla come chiave primaria dell'immagine del gatto nel database (o semplicemente potevo hash i primi n bit dei dati dell'immagine del gatto ). In questo modo dovrei solo verificare la presenza di collisioni.

Esiste un modo standard e best practice per evitare di esporre i volumi di traffico tramite i tuoi URL identificativi univoci?

Modifica: sono in particolare alla ricerca di una soluzione che sia una buona combinazione di sicurezza e idoneità come chiave primaria del database o colonna indicizzabile.

C'è qualche motivo per cui non puoi usare un numero casuale per ogni risorsa? Non c'è bisogno di hashish.
Usare [moltiplicative inverse] (http://ericlippert.com/2013/11/14/a-practical-use-of-multiplicative-inverses/) sarebbe abbastanza "sicuro"?
Tredici risposte:
Rory McCune
2015-12-13 22:52:39 UTC
view on stackexchange narkive permalink

L'approccio standard a questo tipo di problema consiste nel creare un UUID (Universally Unique Identifier) ​​ per ogni immagine. Questo è generalmente un identificatore casuale a 128 bit che puoi assegnare a ciascuna immagine senza alcuna preoccupazione particolare che sarebbe possibile enumerare le immagini tramite un attacco di forza bruta allo spazio dei nomi.

Ad esempio in. NET puoi usare la struttura GUID per questo tipo di scopo. A partire da Windows 2000 ( origine), Guid.NewGuid genera un UUID casuale (versione 4). (Le versioni antiche generavano un versione 1 UUID che rivela la data in cui è stato generato, senza fare nulla per proteggerti dal problema del "numero di fattura".)

Gli UUID v4 non vengono generati da un PRNG crittograficamente forte, rendendoli opportunamente casuali?
@AndréBorie: Il principale svantaggio in termini di prestazioni che ho osservato utilizzando gli UUID come chiavi primarie è che gli UUID casuali non sono adatti per l'uso come indice cluster, che è l'impostazione predefinita di SQL Server per un PK. Quindi è necessario assicurarsi di configurare la tabella in modo appropriato e impostare la chiave primaria come NON CLUSTER.
@Escher [La specifica] (https://www.itu.int/rec/T-REC-X.667-200409-S/en) "consiglia vivamente" un RNG crittograficamente sicuro, ma non vieta di utilizzare un non- assicurane uno.
Nota su UUID rispetto a CSPRNG: la migliore delle due parole sarebbe generare il numero con un CSPRNG e quindi renderlo un UUID v4 tramite maschera di bit.
Una discussione estesa su questi punti dovrebbe andare a DBA.SE ma dagli UUID PoV di un DBA può essere problematico. Nella loro forma naturale sono cattivi candidati per le chiavi raggruppate, portando a una frammentazione molto eccessiva. Il compromesso "UUID sequenziali" in SQL Server risolve questo problema ma ricrea il problema di indovinare la chiave. La loro dimensione può anche essere più un problema di quanto alcuni presumano: oltre a 12 byte extra per riga di dati (rispetto a una chiave intera a 32 bit) ci sono 12 byte extra per riga sugli indici pertinenti (e 12 per riga su * tutti * gli indici se la tua chiave di clustering in un UUID).
@David Spillett, la risposta è "non raggruppare su un UUID". Gli indici chiave non devono essere indici cluster.
@GreenstoneWalker: Sì, ma a volte non c'è nemmeno un'altra chiave di clustering veramente utile, e in ogni caso molte persone usano il clustering sul loro PK senza nemmeno pensarci. Quello che sto cercando di dire è "pensaci in anticipo e tu e / o il tuo amministratore delegato ti ringrazieranno più tardi" (e penso che tu sia d'accordo).
Ángel
2015-12-14 02:07:05 UTC
view on stackexchange narkive permalink

Userei semplicemente l'hash delle immagini. Qual è il problema con qualcuno che scopre l'hash che hai usato? Se penso che "questa parte dell'url sembra sha1", scarica il file e ha quello sha1, avevo ragione. Ma questo non mi rende in grado di violare la tua «sicurezza del gatto». Anche se fosse curabile tentare di rompere l'hash per capire l'immagine, non ha senso provarlo invece di scaricarlo semplicemente.

Tranne che se due utenti caricano la stessa immagine di gatto (entrambi da un'altra parte), quale utente la "possiede" (ad esempio, può eliminarla)? Ciò presuppone che vietare i duplicati non sia di per sé un vantaggio.
@abligh, bene, in questo caso mi limiterò a tenere un elenco di utenti che lo hanno caricato e non lo hanno eliminato. Ma ovviamente dipende dal caso d'uso. Ci sono casi in cui è necessario nascondere il fatto che i due documenti di utenti diversi sono in realtà gli stessi, nel qual caso puoi semplicemente lanciare l'ID utente nel contenuto con hash.
Se non si trattava di immagini di gatti ma di file ZIP di grandi dimensioni (ad esempio), questo metodo impedirebbe anche il caricamento di file duplicati.
@abligh Non è necessario utilizzare la chiave primaria come metodo per trovare l'immagine in un tipico percorso URL. Ad esempio, potresti avere `mysite.com / users / user_id / pictures / image_hash` o` mysite.com / pictures / image_has / users / user_id`. Immagino che quello che sto cercando di dire è che fintanto che imponi l'associazione `immagine <--> utente`, l'hash dell'immagine potrebbe essere usato per cercare l'immagine nel database (come qualsiasi altra colonna) invece del chiave primaria intera, quindi solo l'utente associato all'id dell'immagine potrebbe eliminarla. Se non hai forzato il caricamento degli accessi, questo è un altro problema.
@Prinsig E file diversi con lo stesso hash
Philipp
2015-12-13 23:09:08 UTC
view on stackexchange narkive permalink

Genera semplicemente un hash crittograficamente sicuro dei dati dell'immagine e usalo come identificatore.

Questo ha due effetti collaterali:

  • Le persone possono capire se un'immagine esiste già sul tuo servizio chiedendo un'immagine con quell'hash.
  • Le persone non possono caricare immagini duplicate.

Entrambi questi effetti non sono intrinsecamente dannosi. Potrebbero persino tornare utili. Ma se vuoi evitarli, puoi aggiungere a ogni hash immagine un numero pseudocasuale da un generatore di numeri casuali sicuro.

Le collisioni non sono nulla di cui preoccuparsi, comunque. Con una funzione hash come SHA256, le possibilità di una collisione casuale sono così astronomicamente ridotte, sarebbe una sensazione trovarne una.

Penso che un altro effetto collaterale sarebbe il requisito di URL di immagini di gatti lunghi: P
* Le persone non possono caricare ** esatte ** immagini duplicate *. Apri un file .jpg, "salva con nome" e hash entrambi i file. È * possibile * che il tuo software rilevi che non ci sono modifiche e scriva i dati originali, ma modifica un pixel in qualsiasi formato immagine e l'hash sarà diverso. Quindi non impedisci nemmeno in modo affidabile alle persone di caricare la * stessa * immagine accidentalmente dato che la "stessa" immagine potrebbe non essere lo stesso file (ad esempio il ridimensionamento automatico su dispositivi mobili). [Hash immagine] (http://stackoverflow.com/q/998662/2583476) lo risolverebbe, ma non è un hash sicuro. Può non avere importanza, ovviamente.
@Chris con servizi di hosting di immagini del mondo reale (come Imgur, ad esempio), un caso d'uso comune è prendere un file immagine ottenuto altrove e caricarlo così com'è, senza alcuna modifica, senza modificare un singolo pixel, nemmeno aprendolo in un editor di immagini e premendo "Salva con nome". Probabilmente è abbastanza comune che le persone caricino immagini identiche bit per bit.
@DavidConrad, Sono sicuro che sia comune. Anche il ricaricamento di un'immagine non identica al bit probabilmente è: su http il mio provider di telefonia mobile * a volte * ricomprime le immagini (rendendo ad esempio le mappe inutili nel processo). Ricaricalo e non avrà lo stesso hash, senza alcuna azione da parte dell'utente per modificarlo.
Il punto è che l'affermazione "Le persone non possono caricare duplicati di immagini esatti" è sbagliata.
user253751
2015-12-14 03:33:05 UTC
view on stackexchange narkive permalink

Il modo standard è semplicemente quello di generare in modo casuale i tuoi URL, utilizzando un generatore di numeri pseudo-casuali crittograficamente sicuro (CSPRNG).

Non c'è bisogno di hashing o simili - usa semplicemente vecchi numeri casuali. Non è necessario che siano GUID (a meno che il database non gestisca i GUID meglio dei semplici numeri per qualche motivo). Presumibilmente il tuo sito ricorda già quale immagine è accessibile a ciascun URL, quindi modificala per gestire URL casuali anziché sequenziali.

Un numero casuale a 128 bit dovrebbe essere abbastanza lungo.

Ricorda di verificare la presenza di URL duplicati durante l'elaborazione di nuove immagini.

L'utilizzo di un UUID (o GUID) significa che non è necessario verificare la presenza di duplicati: la "U" sta per Unique e fa parte della garanzia di un UUID o GUID. Ma un UUID non offre necessariamente una garanzia di imprevedibilità. Un generatore di numeri pseudocasuali (CSPRNG) crittograficamente sicuro utilizzato per generare un numero sufficiente di bit fornisce entrambi.
@JohnDeters La maggior parte degli UUID sono di tipo 5 UUID, che sono solo numeri casuali con un indicatore "questo è un numero casuale" appiccicato.
Sono d'accordo. RFC sezione 6. Considerazioni sulla sicurezza, inizia con: "Non dare per scontato che gli UUID siano difficili da indovinare; non dovrebbero essere usati come capacità di sicurezza (identificatori il cui semplice possesso concede l'accesso), per esempio." Ma se usi un CSPRNG per generare un numero abbastanza grande, sarà difficile indovinare. Un hash di una foto non è un seme adatto per un CSPRNG.
@immibis, sei libero di astenervi dal modificare altre risposte se preferisci, ma non è esattamente la politica di Stack Exchange. Vedi http://security.stackexchange.com/help/editing e http://security.stackexchange.com/help/privileges/edit. Se ritieni che le mie modifiche non abbiano migliorato la tua risposta o peggiorato la situazione, hai il potere di ripristinare le modifiche. (Personalmente, ho ritenuto che la mia modifica fosse un miglioramento e, dopo aver aggiunto gli avvertimenti aggiuntivi che ho aggiunto nella mia modifica, questa diventa la migliore risposta alla domanda ... ma sentiti libero di formare la tua opinione.)
Aldian
2015-12-15 15:52:01 UTC
view on stackexchange narkive permalink

Da quello che ho letto nella domanda, nei commenti e in altre risposte, tutto gira intorno alla ricerca di un identificatore univoco per ogni immagine, che non è indovinabile, né fornirebbe informazioni sul numero di immagini e facile da gestire in un database.

Allora, perché non usi solo il timestamp di inserimento (numero di millisecondi dal 1970)? Se c'è una probabilità che due persone inseriscano un'immagine di gatto nello stesso millisecondo, puoi concatenarla con un numero sequenziale corrispondente al numero di inserimenti in quel millisecondo.

In questo modo l'unica cosa che qualcuno in modo aggressivo cercando la tua ultima foto scoprirai che è l'ultima volta che qualcuno ha aggiunto una foto a condizione che tu lasci che un tale idiota faccia quello che sembrerebbe un attacco quotidiano.

Nel frattempo non avresti problemi con le collisioni o il supporto del database.

4chan fa qualcosa di simile ed è pieno di immagini
Philipp
2015-12-13 23:22:04 UTC
view on stackexchange narkive permalink

Soluzione alternativa:

aggiungi metadati agli identificatori di immagine. Esempio:

philipp_20151213_00002.jpg - Seconda immagine pubblicata dall'utente Philipp il 13 dicembre 2015.

Faccio trapelare quei metadati, ma sono solo i dati che un utente può vedere comunque quando si fa clic su quel collegamento (presumo).

Questo non dice a un osservatore quante immagini sono state postate in totale sul tuo servizio, solo sull'attività di quel particolare utente in quel particolare giorno. Se vuoi nascondere anche questo, puoi usare numeri pseudocasuali invece di numeri sequenziali. Le collisioni potrebbero ancora essere possibili quando un singolo utente carica una grande quantità di immagini in un giorno, ma saranno abbastanza rare da poterle gestire semplicemente generando nuovi numeri casuali finché non ne avrai una che non è stata scattata.

Jonathan Gray
2015-12-13 22:55:32 UTC
view on stackexchange narkive permalink

Ecco un metodo. Mantieni un CSPRNG a livello di server da 8 byte. Quindi per ogni nuova immagine, genera un altro CSPRNG da 8 byte. Hash questo CSPRNG con il tuo CSPRNG a livello di server (md5 va bene). Quindi XOR gli ultimi 8 byte dell'hash con l'ID immagine (che aumenterà automaticamente da 0 in un database). Il client riceverà una codifica Base64 dell'esclusivo CSPRNG a 8 byte dell'immagine insieme al risultato XOR a 8 byte. Questo sarà l'ID dell'immagine pubblica.

Quando il server riceve l'ID dell'immagine pubblica, eseguirà l'hash dei primi 8 byte dell'ID pubblico insieme agli 8 byte CSPRNG a livello di server. Quindi prenderà gli ultimi 8 byte dell'hash e lo XOR con gli ultimi 8 byte dell'ID pubblico. Il risultato sarebbe l'ID interno privato che può essere indicizzato dal database.

Aggiorna (spiegazione):

Innanzitutto, pre-definire un globale casuale CSPRNG che verrà utilizzato per tutti i calcoli ID (8 byte o 64 bit con 18.446.744.073.709.551.616 combinazioni possibili).

  serverCSPRNG = CSPRNG (8)  

Per creando un nuovo ID pubblico (16 byte) da un ID privato (8 byte), procedi come segue:

  newCSPRNG = CSPRNG (8) hashEnding = last8Bytes (md5 (newCSPRNG + serverCSPRNG)) publicID = newCSPRNG + XOR (hashEnding, privateID)  

Per derivare il privateID da publicID:

  hashEnding = last8Bytes (md5 (first8Bytes (publicID) + serverCSPRNG) ) privateID = XOR (hashEnding, last8Bytes (publicID))  

Per una maggiore sicurezza, un CSPRNG secondario globale (solo server statico) può essere XOR sugli ultimi 8 byte del publicID al fine di proteggerlo completamente dagli attacchi di forza bruta (poiché implementa il modello di sicurezza inhe affitto di un one-time-pad).

Questo è più complesso del semplice utilizzo di un numero casuale. Ci sono alcuni vantaggi specifici che offre? Inoltre, se vuoi davvero proporre questo, potresti voler usare la matematica per descrivere il tuo schema; probabilmente sarà più facile da seguire. Infine, 8 byte sono sufficienti? Se ci sono $ 2 ^ {32} $ immagini, allora per il paradosso del compleanno, un utente malintenzionato può stimare approssimativamente quante immagini hai facendo qualcosa come $ 2 ^ {32} $ sonde, quindi sospetto che faresti meglio a usare 128 bit o giù di lì.
@D.W. Proverò a chiarirlo usando un approccio più matematico, come suggerisci. Ci saranno effettivamente 2 ^ 64 (18.446.744.073.709.551.616) possibili combinazioni con 8 byte (questa è una protezione a 64 bit). Tuttavia, questo approccio non è semplicemente fragile usando i normali metodi di forza bruta. È più un approccio una tantum. Questo perché la forza bruta viene eseguita sul server CSPRNG, che richiederebbe la conoscenza preliminare di un ID pubblico insieme all'ID interno associato. Questo potrebbe anche essere superato con un CSPRNG lato server secondario (per la vera protezione a 128 bit).
@D.W. Per quanto riguarda i vantaggi specifici, altri metodi richiedono l'uso di valori che probabilmente utilizzeranno implementazioni che richiedono una colonna indicizzata aggiuntiva in un database. Questo metodo deriva l'ID pubblico * dopo l'inserimento della riga *, il che potrebbe essere vantaggioso. Inoltre, questo metodo scalerà meglio in una configurazione in cluster in cui viene utilizzato un database master. Non è inoltre necessario compensare gli errori dovuti alla possibilità di inserire un valore non univoco in una colonna che richiede valori univoci (se opportunamente implementato).
Grazie per l'aggiornamento: la nuova descrizione rende le cose molto più chiare. Tuttavia, non penso che 8 byte siano sufficienti. Un attaccante a forza bruta deve solo indovinare il valore `serverCSPRNG`, che è di soli 64 bit, quindi un attacco a forza bruta richiede solo 2 ^ 64 md5 calcoli. Questo è al di sotto di quanto raccomandato oggi e potrebbe essere fattibile a una spesa non irragionevole. Vedo i vantaggi; simpatico. Tuttavia, suggerirei uno schema leggermente diverso: ad esempio, suggerirei `publicID = E (K, privateID)` dove `K` è una chiave del server a 128 bit e` E` è un metodo di crittografia forte (AES?) .
@D.W. Ho scelto questo metodo rispetto alla crittografia avanzata in quanto è più efficiente. Ma anche come stavo cercando di spiegare (forse non ero chiaro) è che quando si forza bruta non c'è modo di determinare se il valore lo hai corretto o meno. Esistono modi deterministici per indovinarlo, ma anche questa possibilità viene rimossa utilizzando un secondo valore casuale di 8 byte a livello di server. L'aggiunta del secondo valore casuale completerebbe i requisiti per una crittografia "perfetta" completamente non deterministica. È un po 'più complicato di un one-time-pad, ma il concetto è praticamente lo stesso.
* "quando forzando bruta non c'è modo di determinare se il valore lo hai corretto o meno" * - Non penso che sia corretto. Ho il sospetto che gli ID privati ​​spesso avranno una struttura che consenta di verificare un'ipotesi corretta in `serverCSPRNG` (ad esempio, se gli ID privati ​​sono sequenziali): indovina` serverCSPRNG`, esegui una decrittazione di prova e controlla se l'ID privato risultante ha il giusta struttura / formato.
@D.W. Gli ID privati ​​sono sequenziali, sì, ma quel valore è in definitiva XOR con un hash derivato con l'aiuto di un valore casuale. A causa del modo in cui è derivato matematicamente, qualsiasi ID pubblico possibile risulterà in un ID privato valido. Non c'è davvero alcun modo per verificare qualsiasi parte della crittografia per utilizzare un attacco di forza bruta contro questo, specialmente se si utilizza il CSPRNG secondario (ciò impedirebbe un attacco contro un ID privato noto). In effetti, conoscere un server CSPRNG sarebbe vantaggioso solo per forzare l'altro (supponendo che l'ID privato sia noto).
Vorrei sottolineare che so che è possibile, conoscendo più ID pubblici sequenziali, ottenere informazioni sufficienti per la forza bruta contro il server CSPRNG originale. Tuttavia, in questo caso, le collisioni di hashing funzionano effettivamente a nostro favore rendendo possibili falsi positivi. Non è carino. L'uso aggiuntivo del CSPRNG secondario a livello di server è una protezione aggiuntiva che impedirebbe comunque la perdita di ID interno derivante dalla compromissione (forza bruta) del primo. Senza questo, tutto ciò che possono davvero tracciare è la sequenza.
RobIII
2015-12-16 21:02:41 UTC
view on stackexchange narkive permalink

Come notato qui: hash, UUID ecc. hanno lo `` svantaggio '' che gli inserimenti di record nel DB in cui questi hash / uuid sono il PK e il PK è raggruppato sono probabilmente molto costosi (definire costoso ...) poiché di solito non sono sequenziali (a meno che non venga utilizzata una funzione specifica come NEWSEQUENTIALID , tuttavia: nota il blocco "importante" su quella pagina: " Se la privacy è un problema, non utilizzare questa funzione. È possibile indovinare il valore del successivo GUID generato ... ").

A parte i suggerimenti qui lo farei considera qualcosa come il fiocco di neve di Twitter ( fuori produzione). Ho scritto una libreria .Net simile ( IdGen); il file readme contiene alcune informazioni su come funziona esattamente. Il vantaggio è che gli ID generati sono ancora (per lo più) sequenziali, non troppo dispendiosi in termini di spazio (64 bit contro UUID a 128 bit / hash) e possono essere utilizzati in un ambiente distribuito (non coordinato) in cui sono presenti diversi host / processi che generano ID senza causare collisioni. E sebbene siano sequenziali, non forniscono molte informazioni sul numero di foto di gatti (o, più in generale, sul numero di "ID utilizzati") in un certo periodo di tempo.

Peter Taylor
2015-12-16 23:00:16 UTC
view on stackexchange narkive permalink

Questo suona come un lavoro per un algoritmo di hashing, giusto?

No, perché come osservi devi preoccuparti delle collisioni. A me sembra un lavoro per una permutazione, cioè un codice a blocchi. Ciò richiede la gestione di una chiave, che è lo svantaggio, ma ti consente di utilizzare la funzione di incremento automatico del database e di non preoccuparti delle collisioni.

La parte difficile è decidere cosa fare con l'IV , e qui hai opzioni. Potresti generarne uno nuovo ogni volta che crei un URL, quindi ci sarà potenzialmente ad es. 2 ^ 128 URL diversi per immagine di gatto. È possibile impostare l'IV per utente o per sessione e memorizzarlo sul lato server come parte del profilo utente / stato della sessione. Potresti persino renderlo per utente ma incluso nell'URL, in modo da poter monitorare chi riesce a rendere virali le immagini.

Alfred Armstrong
2015-12-14 23:29:07 UTC
view on stackexchange narkive permalink

Un approccio consiste nell'utilizzare hashid.

Hashids è una piccola libreria open source che genera ID brevi, univoci e non sequenziali dai numeri.

Converte numeri come 347 in stringhe come "yr8", o un array di numeri come [27, 986] in "3kTMd".

Puoi anche decodificare quegli ID indietro. Ciò è utile per raggruppare diversi parametri in uno o semplicemente utilizzarli come UID brevi.

Le prestazioni del database non vengono compromesse poiché è possibile continuare a utilizzare internamente ID sequenziali numerici. Nel frattempo i tasti esterni sono opachi.

Tieni presente che gli hashid non sono crittografati: http://carnage.github.io/2015/08/cryptanalysis-of-hashids/ gli id ​​possono essere restituiti ai numeri da un avversario sufficientemente motivato
Penso che gli hashid siano ragionevoli per questo caso d'uso. Sebbene gli hashid siano reversibili, iniziano in modo breve, sono garantiti per essere unici e impedisce alle parole inglesi offensive (come fuck) di apparire come hash. La reversibilità può essere mitigata utilizzando un grande segreto. Non sarà * crittografato * come un UUID, ma ha molte proprietà che sono desiderabili per i numeri di fattura rivolti ai clienti.
Non tutti i casi richiedono la sicurezza crittografica. Quando è necessario, preferisco GUID arbitrari.
Burhan Khalid
2015-12-16 12:54:06 UTC
view on stackexchange narkive permalink

Ho una soluzione a bassa tecnologia a questo problema. Utilizza semplicemente un servizio di abbreviazione dell'URL o scrivi il tuo.

Fornisce quanto segue:

  1. Il tuo URL pubblico non è esposto sui siti di social media.
  2. È garantito che i tuoi URL siano casuali e arbitrari.
  3. Sei libero di modificare l'implementazione sottostante della denominazione delle risorse e i link esterni continueranno a funzionare.
  4. Condivisione più semplice http://catpic.to/i34dhY vs. http://catpictures.com/some-guid-string.
  5. L'ID univoco è facilmente indicizzato / cercato.

Se non vuoi fare affidamento su un servizio di terze parti, puoi facilmente eseguire il rollio implementando una funzione biiettiva nella lingua a tua scelta.

Ian Ringrose
2015-12-16 21:49:10 UTC
view on stackexchange narkive permalink

  • Vorremmo avere un numero sequenziale; altrimenti diventa costoso aggiungere record al database poiché la parte centrale degli indici deve essere aggiornata in un ordine quasi casuale.
  • Non vogliamo che il numero si riferisca al numero di gatti caricati.
  • Abbiamo bisogno che il numero sia univoco ma solo all'interno del tuo sito web.

Pertanto:

  • nextCat è impostato su 0 quando il sito web viene per la prima volta avviato, probabilmente dovrà essere a 64 bit.
  • nextCat è incrementato ogni volta che viene aggiunto un gatto e newCat è impostato su true.
  • nextCat viene incrementato da un timer casuale che si attiva a una velocità maggiore di quella che ti aspetti che vengano aggiunti gatti. Tuttavia, se newCat è true , l'incremento non viene eseguito per questo timer e newCat è impostato su false .
  • A ogni gatto viene anche assegnato un GUID, ma non è mai necessario trovarlo in base al suo GUID
  • l'indirizzo web di un gatto è qualcosa.com/cats/catNumber-catGuid
  • se quando viene richiesto un gatto il catGuid è sbagliato, viene data la stessa risposta per un catNumber che non si riferisce a un gatto.

(Il timer è fatto per un tempo casuale, in modo che sia difficile dire se due gatti vengono aggiunti tra uno scatto del timer.)

Quindi gli indici dei gatti sono ad esempio 0, 1, 4, 7, 8, 10, 12, 15, ecc.? Se conoscessi la distribuzione utilizzata per generare l'intervallo casuale, potresti prendere il valore atteso e dividere la differenza tra gli indici dei gatti a distanza di 24 ore per ottenere una stima abbastanza buona dei gatti generati durante quel periodo.
Grazie @Escher, ho aggiornato la mia risposta quindi è molto difficile trovare gli indici dei gatti.
fredogone
2015-12-14 02:04:15 UTC
view on stackexchange narkive permalink

Best practice generale: non esporre mai il PKEY in nessun collegamento web.

Nel tuo database - il tuo PKEY deve essere un BIGINT per la velocità. Anche nel tuo database, considera l'aggiunta di questo campo ... ( public_filename ..se non esiste) alla tua tabella. Il campo public_filename deve essere una stringa guid. Usa una funzione guid per rinominare il file con un nome file univoco al momento del caricamento sul tuo server e popola public_filename con quello.

Il public_filename dovrebbe essere utilizzato per i collegamenti web, non per il PKEY.

Inoltre, consiglio di mantenere un campo nome_file_utente per supportare qualsiasi ricerca forense dall'uploader, se lo consenti. nome_file_utente sarebbe il nome del file originale caricato dall'utente.

Non esporre mai il PKEY in nessun collegamento web - usa sempre una qualche forma di nome_file_pubblica . Utilizza le query del tuo database per de-referenziare public_filename a un PKEY e da lì puoi capire quale file servire dal server.

Un'altra best practice: non sovrascrivere mai un gli utenti vengono caricati automaticamente. Rinomina il campo nome_file_utente con una serializzazione (-001, -002).

È probabile che tu riceva molti file denominati "micio" dallo stesso utente.

Non c'è niente di sbagliato nell'esporre la chiave primaria. È comune usare hash (dati) come chiave.
Navin: le stringhe hash come chiavi primarie sono molto lente. Perché dovresti volerlo? forense - non hai una sequenza veloce.
fredogone - Memorizza l'hash in un int a 64 bit, non in una stringa. Devi solo eseguire l'hashing dell'immagine quando viene aggiunta al tuo sistema. Quando l'utente vuole recuperarlo, deve ricordare l'hash.
Navin: hai appena eliminato la sequenza forense, a meno che non mantieni un altro campo per acquisire il timestamp.
Bene, se mai aggiorni / modifichi le righe, un ID con incremento automatico non ti darà neanche la sequenza.
No, cosa sta cercando la prova forense, vero? Ma se stavi cercando righe create tra un intervallo di righe, ti darebbe ... un ID con incremento automatico.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...