将十六进制转换为字母数字(PHP)


Convert hex to alphanumeric (PHP)

从十六进制源开始,我想将其转换为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;
}