Domanda

Ho una semplice domanda che si è verificata 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?

È stato utile?

Soluzione

Vorrei usare VARCHAR per dati a lunghezza variabile, ma non con dati a lunghezza fissa. Poiché un valore SHA-1 è sempre lungo 160 bit, il VARCHAR perderebbe solo un byte aggiuntivo per la lunghezza del campo a lunghezza fissa .

E non vorrei nemmeno memorizzare il valore SHA1 sta tornando. Perché usa solo 4 bit per carattere e quindi avrebbe bisogno di 160/4 = 40 caratteri. Ma se usi 8 bit per carattere, avrai solo bisogno di un campo lungo 160/8 = 20 caratteri.

Quindi ti consiglio di usare BINARY (20 ) e il Funzione UNHEX per convertire il valore SHA1 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. Motore InnoDB .

Altri suggerimenti

Un hash SHA1 è lungo 40 caratteri!

Riferimenti tratti da questo blog:

Di seguito è riportato un elenco di algoritmi di hashing con le relative dimensioni in bit richieste:

  • MD5 = valore hash a 128 bit.
  • SHA1 = valore hash a 160 bit.
  • SHA224 = valore hash di 224 bit.
  • SHA256 = valore hash a 256 bit.
  • SHA384 = valore hash a 384 bit.
  • SHA512 = valore hash a 512 bit.

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)
);

Le dimensioni di output di sha1 sono 160 bit. Che è 160/8 == 20 caratteri (se usi caratteri a 8 bit) o ??160/16 = 10 (se usi caratteri a 16 bit).

Quindi la lunghezza è compresa tra 10 caratteri a 16 bit e 40 cifre esadecimali.

Decidi in ogni caso il formato che intendi memorizzare e imposta il campo su una dimensione fissa in base a quel formato. In questo modo non avrai alcuno spazio sprecato.

Potresti comunque voler usare VARCHAR nei casi in cui non memorizzi sempre un hash per l'utente (ad es. 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. Puoi creare una tabella separata per memorizzare l'hash temporaneo - > associazioni di utenti che potrebbero essere eliminate, ma non credo che molte persone si preoccupino 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 via e-mail, quindi nella pagina di destinazione la query entra solo con il token. In questo caso, secondo me, CHAR (40) con INDEX è la scelta migliore :)

Se vuoi adottare questo metodo, ricorda di lasciare $ raw_output = false.

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