在MySQL中存储SHA1哈希值

当我想将SHA1散列的结果存储在MySQL数据库中时,发生了一个简单的问题:

VARCHAR字段应该存储多长时间的散列结果?

我将使用VARCHAR作为可变长度数据,但不使用固定长度的数据。 由于SHA-1值总是 160位长,因此VARCHAR只会浪费固定长度字段长度的附加字节 。

而且我也不会存储SHA1返回的值。 因为它只使用每个字符4位,因此需要160/4 = 40个字符。 但是,如果您使用每个字符8位,则只需要160/8 = 20个字符长的字段。

所以我build议您使用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 ); 

百万loggingbinary(20)需要44.56M,而char(40)需要64.57M。 InnoDB引擎。

一个SHA1哈希是40个字符长!

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

从这个博客引用:

下面是哈希algorithm的列表以及它的要求位大小:

  • MD5 = 128位散列值。
  • SHA1 = 160位散列值。
  • SHA224 = 224位散列值。
  • SHA256 = 256位散列值。
  • SHA3​​84 = 384位散列值。
  • SHA512 = 512位散列值。

用CHAR(n)创build一个样本表

 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') ,SHA1('SamplePass') ,SHA2('SamplePass',224) ,SHA2('SamplePass',256) ,SHA2('SamplePass',384) ,SHA2('SamplePass',512) ); 

所以长度在10个16位字符和40个hex数字之间。

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

如果您不总是为用户存储散列(即authentication帐户/忘记loginURL),您可能仍然希望使用VARCHAR。 一旦用户已经authentication/改变他们的login信息,他们就不应该能够使用散列,并应该没有理由。 你可以创build一个单独的表来存储临时的哈希 – >用户关联,可以删除,但我不认为大多数人打扰这样做。

如果你需要sha1列的索引,我build议CHAR(40)出于性能原因。 在我的情况下,sha1列是电子邮件确认标记,因此在着陆页上,查询只能使用标记进入。 在这种情况下,CHAR(40)与INDEX,在我看来,是最好的select:)

如果你想采用这种方法,记得离开$ raw_output = false。