Pregunta

Tengo una pregunta simple que surgió cuando quise almacenar el resultado de un hash SHA1 en una base de datos MySQL:

¿Cuánto tiempo debe durar el campo VARCHAR en el que almaceno el resultado del hash?

¿Fue útil?

Solución

Yo usaría VARCHAR para datos de longitud variable, pero no con datos de longitud fija. Debido a que un valor SHA-1 tiene siempre 160 bits de longitud, el VARCHAR solo desperdiciaría un byte adicional para la longitud del campo de longitud fija .

Y tampoco almacenaría el valor SHA1 está regresando. Porque utiliza solo 4 bits por carácter y, por lo tanto, necesitaría 160/4 = 40 caracteres. Pero si usa 8 bits por carácter, solo necesitará un campo de 160/8 = 20 caracteres de longitud.

Por lo tanto, te recomiendo que uses BINARIO (20 ) y el UNHEX función para convertir el valor SHA1 a binario.

Comparé los requisitos de almacenamiento para BINARY (20) y 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 millones de registros binario (20) toma 44.56M, mientras que char (40) toma 64.57M. Motor InnoDB .

Otros consejos

¡Un hash SHA1 tiene 40 caracteres de largo!

Referencia tomada de este blog:

A continuación se muestra una lista de algoritmos de hash junto con su tamaño de bit requerido:

  • MD5 = valor hash de 128 bits.
  • SHA1 = valor hash de 160 bits.
  • SHA224 = valor hash de 224 bits.
  • SHA256 = valor hash de 256 bits.
  • SHA384 = valor hash de 384 bits.
  • SHA512 = valor hash de 512 bits.

Creó una tabla de muestra que requiere 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)
);

El tamaño de salida de sha1 es de 160 bits. Que es 160/8 == 20 caracteres (si usa caracteres de 8 bits) o 160/16 = 10 (si utiliza caracteres de 16 bits).

Por lo tanto, la longitud está entre 10 caracteres de 16 bits y 40 dígitos hexadecimales.

En cualquier caso, decida el formato que va a almacenar y haga que el campo tenga un tamaño fijo basado en ese formato. De esa manera no tendrás ningún espacio perdido.

Es posible que aún desee utilizar VARCHAR en los casos en que no siempre almacene un hash para el usuario (es decir, autentifique cuentas / olvidé la URL de inicio de sesión). Una vez que un usuario ha autenticado / cambiado su información de inicio de sesión, no debe poder usar el hash y no debe tener ninguna razón para hacerlo. Podría crear una tabla separada para almacenar hash temporal - > asociaciones de usuarios que podrían eliminarse, pero no creo que la mayoría de la gente se moleste en hacer esto.

Si necesita un índice en la columna sha1, sugiero CHAR (40) por motivos de rendimiento. En mi caso, la columna sha1 es un token de confirmación de correo electrónico, por lo que en la página de destino la consulta solo ingresa con el token. En este caso, CHAR (40) con INDEX, en mi opinión, es la mejor opción :)

Si desea adoptar este método, recuerde dejar $ raw_output = false.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top