Пожалуйста, объясните это основание 62 PHP функция преобразования / алгоритм
Может кто-нибудь объяснить, пожалуйста, код ниже? Это или указать мне на некоторые ресурсы, проливающие свет:)
Он преобразует целое число в строку 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 ответа
Вы слишком усложняете
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;
}
Более псевдокодийная версия.
// 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
При работе с логарифмами есть формула:
logN (x) = log10 (x) / log10 (N).
Другими словами, журнал числа в базе N равен журналу (в базе 10) числа, разделенного на журнал (снова в базе 10) базы.
Таким образом, вместо создания функции логарифма для каждой базы, такой как база 62, вы можете просто использовать встроенную функцию log10() и соответственно масштабировать числа.
И в этом конкретном алгоритме вы хотите определить, сколько цифр в базе 62 для числа, которое вы конвертируете, так что вы можете использовать это в цикле "for".
Конечно, вы можете сделать это с помощью цикла while без необходимости вычислять log62(n). Это упражнение для читателя.
Надеюсь это поможет.
// 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
}