下面是一个供考虑的小函数:
/** Return 22-char compressed version of 32-char hex string (eg from PHP md5). */
function compress_md5($md5_hash_str) {
// (we start with 32-char $md5_hash_str eg "a7d2cd9e0e09bebb6a520af48205ced1")
$md5_bin_str = "";
foreach (str_split($md5_hash_str, 2) as $byte_str) { // ("a7", "d2", ...)
$md5_bin_str .= chr(hexdec($byte_str));
}
// ($md5_bin_str is now a 16-byte string equivalent to $md5_hash_str)
$md5_b64_str = base64_encode($md5_bin_str);
// (now it's a 24-char string version of $md5_hash_str eg "VUDNng4JvrtqUgr0QwXOIg==")
$md5_b64_str = substr($md5_b64_str, 0, 22);
// (but we know the last two chars will be ==, so drop them eg "VUDNng4JvrtqUgr0QwXOIg")
$url_safe_str = str_replace(array("+", "/"), array("-", "_"), $md5_b64_str);
// (Base64 includes two non-URL safe chars, so we replace them with safe ones)
return $url_safe_str;
}
基本上,MD5 哈希字符串中有 16 字节的数据。它的长度为 32 个字符,因为每个字节都编码为 2 个十六进制数字(即 00-FF)。因此,我们将它们分解为字节,并构建一个16字节的字符串。但是,由于这不再是人类可读或有效的ASCII,因此我们将其编码回可读字符。但是由于 base-64 导致 ~4/3 的扩展(我们每 8 位输入仅输出 6 位,因此需要 32 位来编码 24 位),因此 16 字节变为 22 字节。但是,由于 base-64 编码通常填充到 4 的长度倍数,因此我们只能采用 24 个字符输出的前 22 个字符(其中最后 2 个字符是填充)。然后,我们将 base-64 编码使用的非 URL 安全字符替换为 URL 安全等效字符。
这是完全可逆的,但这是留给读者的练习。
我认为这是你能做的最好的事情,除非你不关心人类可读/ASCII,在这种情况下,你可以直接使用$md 5_bin_str。
此外,如果您不需要保留所有位,则可以使用此函数的结果的前缀或其他子集。抛出数据显然是缩短事情的最简单方法!(但那是不可逆的)
P.S. 对于您输入的“a7d2cd9e0e09bebb6a520af48205ced1”(32个字符),此函数将返回“VUDNng4JvrtqUgr0QwXO0Q”(22个字符)。