从十六进制源开始,我想将其转换为a-zA-Z0-9
。base_convert()只支持32进制作为输出,这等于a-z0-9
。我需要一个base-62输出,用于额外的A-Z
(不知道如何更好地解释,对不起)。
我正在这样做(因为社区经常问),因为我使用openssl rand -hex
作为随机密码的来源(我很想使用rand()等,但我需要有很多唯一的密码,rand()甚至mt_rand()没有提供足够的伤亡,密码经常重复,脚本锁定)。
谢谢。
试试这个:
function base62_encode($hex)
{
$chars = 'abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789';
$in = hexdec($hex);
$result = '';
while ($in > 0) {
$i = $in % 62;
$in = (int)($in / 62);
$result = $chars[$i] . $result;
}
return $result;
}
我也有同样的问题,因为我想用它来缩短url中的32个十六进制UID号。krzysztoof的解决方案对我不起作用,因为将整个十六进制字符串转换为一个32位或64位十进制整数将导致转换为浮点数,并失去128位UID的额外熵。为了修复Krzysztof的解决方案,我在for循环中添加了一个直接对十六进制字符串起作用的基数的手动除法,仅对小的部分除法使用小数:
function hex2setstring($hex)
{
$chars = 'abcdefghijklmnopqrstuwvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ0123456789';
$setbase=strlen($chars);
$answer = '';
while (!empty($hex) && ($hex !== 0) && ($hex !== dechex(0))) {
$hex_result = '';
$hex_remain = '';
// divide by base in hex:
for ($i=0;$i<strlen($hex);$i+=1){
$hex_remain = $hex_remain . $hex[$i];
$dec_remain = hexdec($hex_remain);
// small partial divide in decimals:
$dec_result = (int)($dec_remain/$setbase);
if (!empty($hex_result) || ($dec_result > 0))
$hex_result = $hex_result . dechex($dec_result);
$dec_remain = $dec_remain - $setbase*$dec_result;
$hex_remain = dechex($dec_remain);
}
$answer = $chars[$dec_remain] . $answer;
$hex = $hex_result;
}
return $answer;
}
另一个可能性是
function hexToStr($hex)
{
$s = '';
for ($i = 0; $i < strlen($hex)-1; $i += 2) {
$s .= chr(hexdec($hex[$i] . $hex[$i + 1]));
}
return $s;
}