编辑根据 OP 对此答案的评论。
下面的代码使用 BC Math 库将 MD5 哈希转换为 Base-90 字符串。这会将 32 个字符的字符串转换为 20 个字符的字符串。这与所需的 8 个字符相去甚远,但它是使用 ASCII 范围的最小字符串长度(可以通过使用字符将基数增加到 Base-94,'
"
\
[space]
但这不会影响字符串长度,而是可能在处理数据时导致问题) .
$ip = '200.100.15.117';
$hash = md5($ip);
$chars16 = array(
'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5,
'6' => 6, '7' => 7, '8' => 8, '9' => 9, 'a' => 10, 'b' => 11,
'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15
);
$base10 = '0';
for ($i = strlen($hash) - 1; $i > 0; $i--) {
$base10 = bcadd($base10, bcmul($chars16[$hash[$i]], bcpow(16, $i)));
}
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,;.:-_+*?!$%&@#~^=/<>[](){}`';
$base = (string)strlen($chars);
$baseX = '';
while (bccomp($base10, $base) === 1 || bccomp($base10, $base) === 0) {
$baseX = substr($chars, bcmod($base10, $base), 1) . $baseX;
$base10 = preg_replace('/\.\d*$/', '', bcdiv($base10, $base));
}
$baseX = substr($chars, $base10, 1) . $baseX;
echo $baseX; // Shows: 1BS[JdZf/7J$J{ud&r5i