这里有一个需要考虑的小函数:
/** 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 编码回可读字符。但由于 base-64 导致约 4/3 扩展(每 8 位输入仅输出 6 位,因此需要 32 位来编码 24 位),因此 16 字节变为 22 字节。但由于 base-64 编码通常会填充到 4 的倍数长度,因此我们只能获取 24 个字符输出的前 22 个字符(其中最后 2 个是填充)。然后,我们将 base-64 编码使用的非 URL 安全字符替换为 URL 安全等效字符。
这是完全可逆的,但这留给读者作为练习。
我认为这是你能做的最好的事情,除非你不关心人类可读/ASCII,在这种情况下你可以直接使用 $md5_bin_str 。
如果不需要保留所有位,您还可以使用此函数结果的前缀或其他子集。丢弃数据显然是缩短时间的最简单方法! (但是之后就不可逆了)
附:对于您输入的“a7d2cd9e0e09bebb6a520af48205ced1”(32 个字符),此函数将返回“VUDNng4JvrtqUgr0QwXO0Q”(22 个字符)。