Хранение хэш-значений SHA1 в MySQL

У меня есть простой вопрос, который произошел, когда я хотел сохранить результат хэша SHA1 в базе данных MySQL:

сколько стоит тип varchar поле, в котором я храню результат хэша?

7 ответов


я хотел бы использовать VARCHAR для данных переменной длины, но не с фиксированной длиной данных. Потому что значение SHA-1 всегда 160 бит, то VARCHAR будет просто отходы дополнительный байт для длины поля фиксированной длины.

и я также не буду хранить значение SHA1 возвращается. Потому что он использует только 4 бит на символ и, таким образом, потребуется 160/4 = 40 символов. Но если вы используете 8 бит на символ, вы только нужно 160/8 = 20 символов длинного поля.

поэтому я рекомендую вам использовать BINARY(20) и UNHEX функции преобразование SHA1 значение в двоичный.

я сравнил требования к хранению для BINARY(20) и 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
);

С миллионом записей binary(20) принимает 44.56 м, а char(40) занимает 64.57 М. InnoDB двигатель.


хэш SHA1 имеет длину 40 символов!


ссылка взята из этого блога:

Ниже приведен список алгоритма хэширования вместе с его требуемым битовым размером:

  • MD5 = 128-битное хэш-значение.
  • SHA1 = 160-битное хэш-значение.
  • SHA224 = 224-битное хэш-значение.
  • SHA256 = 256-битное хэш-значение.
  • SHA384 = 384-битное хэш-значение.
  • SHA512 = 512-битный хэш значение.

создан один образец таблицы с require 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)
);

размер выхода sha1 160 битов. Это 160/8 == 20 символов (если вы используете 8-битные символы) или 160/16 = 10 (если вы используете 16-битные символы).


таким образом, длина находится между 10 16-битными символами и 40 шестнадцатеричными цифрами.

в любом случае решите формат, который вы собираетесь хранить, и сделайте поле фиксированным размером на основе этого формата. Так у вас не будет лишнего места.


вы все равно можете использовать VARCHAR в случаях, когда вы не всегда храните хэш для пользователя (т. е. аутентификацию учетных записей/забыли url-адрес входа). Как только пользователь аутентифицировал/изменил свою регистрационную информацию, они не должны иметь возможности использовать хэш и не должны иметь причин. Вы можете создать отдельную таблицу для хранения временных ассоциаций пользователей hash ->, которые могут быть удалены, но я не думаю, что большинство людей беспокоятся об этом.


Если вам нужен индекс в столбце sha1, я предлагаю CHAR (40) по соображениям производительности. В моем случае столбец sha1 является токеном подтверждения электронной почты, поэтому на целевой странице запрос вводится только с токеном. В этом случае CHAR (40) с индексом, на мой взгляд, является лучшим выбором:)

Если вы хотите принять этот метод, не забудьте оставить $raw_output = false.