Reputation: 24324
Could anyone please explain the code below? That or point me to some resources shedding some light :)
It converts an integer to a base62 string.
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;
}
Update: What I meant to ask: Could anyone please explain the algorithm below? :) Thanks.
Upvotes: 1
Views: 1892
Reputation: 154653
You're over-complicating:
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;
}
Upvotes: 5
Reputation: 1021
A more pseudocodey version.
// 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
Upvotes: 1
Reputation: 2021
There is a formula when working with logarithms:
logN(x) = log10(x) / log10(N).
In other words, the log of a number in base N is equal to the log (in base 10) of the number divided by the log (again in base 10) of the base.
So instead of creating a logarithm function for each base, like base 62, you can simply use the native log10() function and scale the numbers accordingly.
And in this particular algorithm, you want to determine how many digits there are, in base 62, for the number you are converting, so you can use that in the "for" loop.
You could, of course, do this is with a while loop without having to calculate log62(n). This is an exercise for the reader.
Upvotes: 1
Reputation: 28893
Hope this helps.
// 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
}
Upvotes: -1