请解释这个基础62 PHP转换函数/算法

时间:2011-01-18 20:49:38

标签: php algorithm base62

有人可以解释下面的代码吗?那或者指出一些资源可以解决一些问题:)

它将整数转换为base62字符串。

private static $_characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

private static function _convertBase($num)
{
    $base = strlen(self::$_characters);
    $string = '';

    for ($t = floor(log10($num) / log10($base)); $t >= 0; $t--) {
        $a = floor($num / pow($base, $t));
        $string .= substr(self::$_characters, $a, 1);
        $num = $num - ($a * pow($base, $t));
    }

    return $string;
}

更新:我的意思是:有人可以解释下面的算法吗? :)谢谢。

4 个答案:

答案 0 :(得分:4)

你太复杂了:

private static $_characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

private static function _convertBase($num)
{
    $base = strlen(self::$_characters); // 62
    $string = self::$_characters[$num % $base];

    while (($num = intval($num / $base)) > 0)
    {
        $string = self::$_characters[$num % $base] . $string;
    }

    return $string;
}

答案 1 :(得分:1)

使用对数时有一个公式:

logN(x)= log10(x)/ log10(N)。

换句话说,基数N中的数字的对数等于数字的对数(在基数10中)除以基数的对数(再次在基数10中)。

因此,您可以简单地使用本机log10()函数并相应地缩放数字,而不是为每个基础创建对数函数,例如base 62。

在这个特定的算法中,你想确定你要转换的数字在基数62中有多少位数,所以你可以在“for”循环中使用它。

当然,您可以使用while循环而无需计算log62(n)。这是读者的练习。

答案 2 :(得分:1)

更伪的伪装版本。

// Maps some characters such that
//  0   ->'0'
//  9   ->'9'
//  10  ->'a'
//  35  ->'z'
//  36  ->'A'
//  61  ->'Z'
Let constant characters = List ('0'..'9', 'a'..'z', 'A'..'Z')
Let constant size = length of characters

Function LogBase(number base, number x)
    Return LogBase10(x) / LogBase10(base)

Function LeftMostPosition(unsigned integer message)
    Return Floor(LogBase(size,message))

Function ShiftRight(unsigned integer message, unsigned integer numberOfPositions)
    Return Floor(message / (size to the numberOfPositions power))

Function ShiftLeft(unsigned integer message, unsigned integer numberOfPositions)
    Return message * (size to the numberOfPositions power)

Function Decode(unsigned integer message)
    Let var buffer be a string buffer

    // Runs a number of times equal to LeftMostPosition(message) + 1
    Count position from LeftMostPosition(message) down through 0
        // Get the symbol from the left side of the message
        Let var index = ShiftRight(message, position)
        // Add the decoded character
        To buffer, add characters[index]
        // And then remove it from the incoming message
        Let message = message - ShiftLeft(index, position)

    Return contents of buffer

答案 3 :(得分:0)

希望这有帮助。

// Define a set of allowable characters
private static $_characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

// Function declaration
private static function _convertBase($num)
{
    $base = strlen(self::$_characters); // Count the number of characters available
    $string = '';                       // Initialize an empty string

    // Start the iterator off as (num / character count). Continue until it is zero.
    for ($t = floor(log10($num) / log10($base)); $t >= 0; $t--) {
        $a = floor($num / pow($base, $t));              // Find the numeric (0-$base) position of the corresponding character.
        $string .= substr(self::$_characters, $a, 1);   // Pull that character out and add it to the return string
        $num = $num - ($a * pow($base, $t));            // Subtract it from $num
    }

    return $string;                    // Return the encoded string 
}