160

当我想将 SHA1 哈希的结果存储在 MySQL 数据库中时,我遇到了一个简单的问题:

我存储哈希结果的VARCHAR字段应该多长时间?

4

7 回答 7

316

我将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)需要 4456 万,而char(40)需要 6457 万。 InnoDB引擎。

于 2009-03-05T12:00:39.560 回答
45

SHA1 哈希是 40 个字符长!

于 2009-03-05T11:58:50.703 回答
11

参考来自这个博客:

以下是哈希算法列表及其所需位大小:

  • MD5 = 128 位哈希值。
  • SHA1 = 160 位哈希值。
  • SHA224 = 224 位哈希值。
  • SHA256 = 256 位哈希值。
  • SHA3​​84 = 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)
);
于 2016-07-28T19:56:37.303 回答
6

sha1 的输出大小为 160 位。这是 160/8 == 20 个字符(如果您使用 8 位字符)或 160/16 = 10(如果您使用 16 位字符)。

于 2009-03-05T12:03:06.200 回答
3

所以长度在 10 个 16 位字符和 40 个十六进制数字之间。

在任何情况下,决定您要存储的格式,并根据该格式使字段的大小固定。这样你就不会浪费任何空间。

于 2009-03-05T12:17:00.833 回答
2

在您不总是为用户存储哈希的情况下(即验证帐户/忘记登录 url),您可能仍希望使用 VARCHAR。一旦用户验证/更改了他们的登录信息,他们就不应该能够使用哈希并且应该没有理由这样做。您可以创建一个单独的表来存储临时哈希-> 可以删除的用户关联,但我认为大多数人不会费心去做。

于 2011-05-25T22:26:15.277 回答
2

如果您需要 sha1 列上的索引,出于性能原因,我建议使用 CHAR(40)。在我的情况下,sha1 列是一个电子邮件确认令牌,因此在登录页面上,查询仅使用令牌输入。在这种情况下,我认为带有 INDEX 的 CHAR(40) 是最好的选择:)

如果要采用这种方式,记得留$raw_output = false。

于 2012-05-31T07:42:55.537 回答