SHA256 の結果を 内に保存できる理由に興味がありますが、同じ結果を保存するにはbinary(32)
が必要です。varchar(64)
つまり、256 ビットは 32 バイトなので、 a 内に保存するbinary(32)
ことは完全に理にかなっています。しかし、それを に保存しようとするとvarchar
、バイトごとに余分なバイトが必要になるのはなぜですか?
最初から始めて、暗号化関数とは何か、実際の出力は何かを見てみましょう。
暗号化ハッシュ関数はハッシュ関数です。つまり、データの任意のブロックを取得し、固定サイズのビット文字列である (暗号化) ハッシュ値を返すアルゴリズムです。
これは、1 と 0 のシーケンスを取得することを意味します。そのシーケンスを正しく保存するには、MySQL のbinary
data-type カラムを使用する必要があります。これは、保存されたデータをユーザーに表示する方法に関するデータが保存されないためです。関連するエンコーディングはありません。つまり、データを表示しようとすると、GUI プログラムが ASCII エンコードされた文字列として格納された値を表現しようとするため (これは間違っています)、文字化けが発生する可能性が高くなります。
ハッシュ値が数値で表される理由については省略しますが、重要なのは数値であるということです。しかも16進数です。使用した最初のバイトを見てみましょう:
10101111
= 10 進数175
または 16 進数AF
です。
確かに、ASCII を何かとして表すことはできますが175
、使用されているコードページによっては、奇妙な文字になる可能性が高くなります。ASCII の問題は、127 を超えるコードは任意であり、コードページの発明、Unicode の発明などにつながることです。そのため、ここでは省略します。
10101111
ポイントは、すべてのシナリオで ASCII が正しく表示されることに頼ることはできないということです。つまり175
、1 バイトではなく 3 バイトを使用して表示する必要があります。なぜですか? の各文字は175
、独自のバイトを使用して表示する必要があるためです。
つまり、ハッシュ値を 10 進数で表示できます。これは、数値を 16 進数で表示できることも意味します。
もう一度撮りましょう10101111
。
10 進数で175
は、画面に表示するのに 3 バイトかかります。1 は1
、1 は7
、1 は です5
。16 進数でAF
は、画面に表示するのに 2 バイトかかります - 大幅に短くなります。
16 進数に変換された各バイトには、少なくとも 2 桁の数字があります (先行ゼロがあります)。10 進数の場合はそうではないため、1 バイトを 16 進数として表現するたびに、少なくとも 2 桁になることがわかります。したがって、メッセージは固定幅であり、すべての ASCII コード ページで同じ位置にある数字 0 ~ 9、文字 A~F を使用するため、同じように見えます。
したがってAF
、ASCII で取得して表示すると、 に 1 バイト、A
に 1 バイトが必要ですF
。32 個の数字があり、それぞれ 2 桁で、32x2 = 64 バイトです。
おそらくあなたが犯した唯一の間違いは、を使用したことvarchar(64)
です。ハッシュ幅がわかっている場合、ハッシュを格納するために varchar を使用しても意味がありません。その列が使用するchar
1バイトを無駄にしないので、使用する方がはるかに優れています。varchar
うまくいけば、これで少しは解決します。実際には、思ったよりも簡単です:)