在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位散列值。
- SHA384 = 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。