Ho una semplice domanda che si è presentata quando volevo archiviare il risultato di un hash SHA1 in un database MySQL:
Quanto deve essere lungo il campo VARCHAR in cui memorizzo il risultato dell'hash?
Ho una semplice domanda che si è presentata quando volevo archiviare il risultato di un hash SHA1 in un database MySQL:
Quanto deve essere lungo il campo VARCHAR in cui memorizzo il risultato dell'hash?
Risposte:
Vorrei utilizzare VARCHAR
per dati a lunghezza variabile, ma non con dati a lunghezza fissa. Poiché un valore SHA-1 è sempre lungo 160 bit, si VARCHAR
perderebbe un byte aggiuntivo per la lunghezza del campo a lunghezza fissa .
E inoltre non memorizzerei il valore SHA1
restituito. Perché usa solo 4 bit per carattere e quindi avrebbe bisogno di 160/4 = 40 caratteri. Ma se usi 8 bit per carattere, avrai bisogno solo di un campo lungo 160/8 = 20 caratteri.
Quindi ti consiglio di usare BINARY(20)
e la UNHEX
funzione per convertire il SHA1
valore in binario.
Ho confrontato i requisiti di archiviazione per BINARY(20)
e CHAR(40)
.
CREATE TABLE `binary` (
`id` int unsigned auto_increment primary key,
`password` binary(20) not null
);
CREATE TABLE `char` (
`id` int unsigned auto_increment primary key,
`password` char(40) not null
);
Con milioni di record binary(20)
richiede 44,56 milioni, mentre char(40)
richiede 64,57 milioni.
InnoDB
motore.
UNHEX()
manualmente a sql.
Un hash SHA1 è lungo 40 caratteri!
Riferimento tratto da questo blog:
Di seguito è riportato un elenco di algoritmi di hashing insieme alle dimensioni dei bit richieste:
Creata una tabella di esempio con richiesta CHAR (n):
CREATE TABLE tbl_PasswordDataType
(
ID INTEGER
,MD5_128_bit CHAR(32)
,SHA_160_bit CHAR(40)
,SHA_224_bit CHAR(56)
,SHA_256_bit CHAR(64)
,SHA_384_bit CHAR(96)
,SHA_512_bit CHAR(128)
);
INSERT INTO tbl_PasswordDataType
VALUES
(
1
,MD5('SamplePass_WithAddedSalt')
,SHA1('SamplePass_WithAddedSalt')
,SHA2('SamplePass_WithAddedSalt',224)
,SHA2('SamplePass_WithAddedSalt',256)
,SHA2('SamplePass_WithAddedSalt',384)
,SHA2('SamplePass_WithAddedSalt',512)
);
Quindi la lunghezza è compresa tra 10 caratteri a 16 bit e 40 cifre esadecimali.
In ogni caso, decidere il formato che si intende memorizzare e rendere il campo di dimensioni fisse in base a tale formato. In questo modo non avrai alcuno spazio sprecato.
Potresti comunque voler utilizzare VARCHAR nei casi in cui non memorizzi sempre un hash per l'utente (ovvero autenticazione di account / URL di accesso dimenticato). Una volta che un utente ha autenticato / modificato le informazioni di accesso, non dovrebbe essere in grado di utilizzare l'hash e non dovrebbe avere motivo di farlo. È possibile creare una tabella separata per memorizzare hash temporanei -> associazioni di utenti che potrebbero essere eliminate, ma non credo che la maggior parte delle persone si preoccupi di farlo.
Se hai bisogno di un indice sulla colonna sha1, ti consiglio CHAR (40) per motivi di prestazioni. Nel mio caso la colonna sha1 è un token di conferma e-mail, quindi nella pagina di destinazione la query entra solo con il token. In questo caso CHAR (40) con INDEX, secondo me, è la scelta migliore :)
Se vuoi adottare questo metodo, ricorda di lasciare $ raw_output = false.