Хранение хеш-значений SHA1 в MySQL - PullRequest
152 голосов
/ 05 марта 2009

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

Как долго должно быть поле VARCHAR , в котором я храню результат хеширования?

Ответы [ 7 ]

305 голосов
/ 05 марта 2009

Я бы использовал 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 двигатель.

41 голосов
/ 05 марта 2009

SHA1 хэш длиной 40 символов!

11 голосов
/ 28 июля 2016

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

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

  • MD5 = 128-битное хеш-значение.
  • SHA1 = 160-битное хеш-значение.
  • SHA224 = 224-битное хеш-значение.
  • SHA256 = 256-битное хеш-значение.
  • SHA384 = 384-битное значение хеш-функции.
  • SHA512 = 512-битное хеш-значение.

Создан один образец таблицы с требованием 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)
);
6 голосов
/ 05 марта 2009

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

3 голосов
/ 05 марта 2009

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

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

2 голосов
/ 31 мая 2012

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

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

2 голосов
/ 26 мая 2011

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

...