MySQLにSHA1ハッシュ値を保存する
-
03-07-2019 - |
質問
MySQLデータベースにSHA1ハッシュの結果を保存するときに発生した簡単な質問があります:
ハッシュの結果を保存する VARCHAR フィールドの長さはどのくらいですか?
解決
可変長データには VARCHAR
を使用しますが、固定長データには使用しません。 SHA-1の値は常に160ビット長であるため、 VARCHAR
は固定長フィールドの長さの追加バイト。
また、 SHA1
が戻ってきています。 1文字につき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
);
100万件のレコードがある場合、 binary(20)
は44.56M、 char(40)
は64.57Mを消費します。
InnoDB
エンジン。
他のヒント
SHA1ハッシュは40文字です!
以下は、必要なビットサイズとともにハッシュアルゴリズムのリストです:
- MD5 = 128ビットのハッシュ値。
- SHA1 = 160ビットのハッシュ値。
- SHA224 = 224ビットのハッシュ値。
- SHA256 = 256ビットのハッシュ値。
- SHA384 = 384ビットのハッシュ値。
- SHA512 = 512ビットのハッシュ値。
require CHAR(n)で1つのサンプルテーブルを作成しました:
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個の16進数の間です。
いずれの場合でも、保存する形式を決定し、その形式に基づいてフィールドを固定サイズにします。 そうすれば、無駄なスペースはありません。
ユーザーのハッシュを常に保存するわけではない場合(つまり、アカウントの認証/ログインURLを忘れた場合)でも、VARCHARを使用することができます。ユーザーがログイン情報を認証/変更したら、ハッシュを使用することはできず、理由もありません。一時ハッシュを保存するために別のテーブルを作成できます->削除される可能性のあるユーザーアソシエーションですが、ほとんどの人がこれを行うことを気にしているとは思いません。
sha1列にインデックスが必要な場合、パフォーマンス上の理由からCHAR(40)をお勧めします。 私の場合、sha1列は電子メール確認トークンであるため、ランディングページではクエリはトークンのみで入力されます。 この場合、私の意見では、INDEX付きのCHAR(40)が最良の選択です:)
この方法を採用する場合は、$ raw_output = falseのままにしてください。