$string
に適用するmd5()
と、私に与える大きな文字列があります
c4ca4238a0b923820dcc509a6f75849b
レングスは32なので短くしたいので
base64_encode(md5($string, true));
xMpCOKC5I4INzFCab3WEmw==
最後の 2 つを削除する==
と、長さ = 22 の文字列が得られます。
他のより良いアルゴリズムはありますか?
md5
これがハッシュ関数であるため、元に戻すことができないことに気付いたかどうかはわかりません。可逆性を気にしない場合は、md5
ハッシュ (または好みのハッシュ*) を任意の文字数にトリミングすることもできます。これが行うことは、衝突の可能性を高めることだけです(ただし、これは均一な分布を生成しないと思います)。
可逆的な (つまり、非破壊的な) 圧縮を探している場合は、車輪を再発明しないでください。gzdeflate()
またはなどの組み込み関数gzcompress()
、または他の同様の関数を使用します。
*ハッシュ関数(ウィキペディア)のリストとその出力サイズを次に示します。可能な限り最小の「ハッシュ関数」はパリティビットになると思います:)
必要な文字列が小さいlength
ほど、数が少なくなりますpossible combination
評判の可能性の総数
可能性の合計 = n r
base64を扱っているため、印刷可能な出力があるため、これは 64 文字しかないことを意味します。
n = 64
長さ22文字を見ている場合
n r = 64 22 = 5,444,517,870,735,015,415,413,993,718,908,291,383,296 の可能性
あなたの質問に戻る: より良いアルゴリズムはありますか?
全体の可能性と衝突が修正されているため、必要な長さに適切なハッシュで文字列を切り捨てます
$string = "the fox jumps over the lazy brown dog";
echo truncateHash($string, 8);
出力
9TWbFjOl
使用する機能
function truncateHash($str, $length) {
$hash = hash("sha256", $str, true);
return substr(base64_encode($hash), 0, $length);
}
より良い方法の 1 つは、(md5 のように) 2 進数から 16 進数に変換してから文字列を base64 に変換する代わりに、16 進数の md5 を直接 base64 に変換することです。
16 進数は 1 文字あたり 16 ビットであり、base64 は 1 文字あたり 64 ビットであるため、2 つの 16 進数文字ごとに 1 つの base64 文字が構成されます。
変換を実行するには、次の操作を実行できます。
これにより、md5 文字列の 16 進表現と同じ値を持つ 16 文字の base64 文字列が生成されます。
理論的には、どのベースでも同じことができます。base128 文字列を ASCII でエンコードする方法があれば、最終的に 8 文字の文字列になる可能性があります。ただ、文字セットが限られているので、base64が一般的に使われている最上位のベースだと思います。
このエンコーディングは、より短い文字列を生成します。
print base64_encode(hash("crc32b",$string,1));
出力
qfQIdw==
Base 91は、最もスペース効率の良いバイナリから ASCII への印刷可能なエンコーディング アルゴリズムのように見えます (これは、あなたが望むものです)。
私は PHP の実装を見たことがありませんが、あなたのソフトウェアが他のソフトウェアと連携する必要がある場合は、Base 64 に固執します。よく知られており、非常に高速で、どこでも利用できます。