Eu tenho uma pergunta simples que ocorreu quando eu queria armazenar o resultado de um hash SHA1 em um banco de dados MySQL:
Quanto tempo deve estar o campo VARCHAR no qual armazeno o resultado do hash?
Eu tenho uma pergunta simples que ocorreu quando eu queria armazenar o resultado de um hash SHA1 em um banco de dados MySQL:
Quanto tempo deve estar o campo VARCHAR no qual armazeno o resultado do hash?
Respostas:
Eu usaria VARCHAR
para dados de comprimento variável, mas não com dados de comprimento fixo. Como um valor SHA-1 sempre tem 160 bits, VARCHAR
seria apenas um byte adicional para o comprimento do campo de comprimento fixo .
E eu também não armazenaria o valor que SHA1
está retornando. Porque ele usa apenas 4 bits por caractere e, portanto, precisaria de 160/4 = 40 caracteres. Mas se você usar 8 bits por caractere, precisará apenas de um campo de 160/8 = 20 caracteres.
Então, eu recomendo que você use BINARY(20)
e a UNHEX
função para converter o SHA1
valor em binário.
Comparei os requisitos de armazenamento para 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
);
Com milhões de registros binary(20)
leva 44,56M, enquanto char(40)
leva 64,57M.
InnoDB
motor.
UNHEX()
manualmente ao sql.
Um hash SHA1 tem 40 caracteres!
Referência retirada deste blog:
Abaixo está uma lista do algoritmo de hash junto com seu tamanho de bit requerido:
Criou uma tabela de amostra com CHAR (n) requerido:
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)
);
O tamanho da saída de sha1 é de 160 bits. Que é 160/8 == 20 caracteres (se você usar caracteres de 8 bits) ou 160/16 = 10 (se você usar caracteres de 16 bits).
Portanto, o comprimento está entre 10 caracteres de 16 bits e 40 dígitos hexadecimais.
De qualquer forma, decida o formato que você deseja armazenar e torne o campo um tamanho fixo com base nesse formato. Dessa forma, você não terá espaço desperdiçado.
Você ainda pode usar o VARCHAR nos casos em que nem sempre armazena um hash para o usuário (ou seja, autenticar contas / esquecer o URL de login). Depois que um usuário tiver autenticado / alterado suas informações de login, ele não poderá mais usar o hash e não deverá ter motivos para isso. Você pode criar uma tabela separada para armazenar hash temporário -> associações de usuários que podem ser excluídas, mas acho que a maioria das pessoas não se preocupa em fazer isso.
Se você precisar de um índice na coluna sha1, sugiro CHAR (40) por razões de desempenho. No meu caso, a coluna sha1 é um token de confirmação de email, portanto, na página de entrada, a consulta entra apenas com o token. Nesse caso, CHAR (40) com INDEX, na minha opinião, é a melhor escolha :)
Se você deseja adotar esse método, lembre-se de deixar $ raw_output = false.