PHP - How to base_convert () to base 62

I need a base_convert() function that works from base 2 to base 62, but I don’t have the math I need to use, I know that due to PHP limitations I need to use bcmath, which is good.

Functions like they convert a number to a base and from base 10 to another base to 62, but I want to implement the same base_convert() functionality, for example: the only function that can convert between arbitrary bases.

I found a function that seems to do this , but it gives me the feeling of having redundant and slow code, and I would kind of fine-tune it if I know German that I don’t have. = (

Here is a more readable version of the function:

 function bc_base_convert($value, $quellformat, $zielformat) { $vorrat = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; if (min($quellformat, $zielformat) < 2) { trigger_error('Bad Format min: 2', E_USER_ERROR); } if (max($quellformat, $zielformat) > strlen($vorrat)) { trigger_error('Bad Format max: ' . strlen($vorrat), E_USER_ERROR); } $dezi = '0'; $level = 0; $result = ''; $value = trim(strval($value), "\r\n\t +"); $vorzeichen = '-' === $value{0} ? '-' : ''; $value = ltrim($value, "-0"); $len = strlen($value); for ($i = 0; $i < $len; $i++) { $wert = strpos($vorrat, $value{$len - 1 - $i}); if (FALSE === $wert) { trigger_error('Bad Char in input 1', E_USER_ERROR); } if ($wert >= $quellformat) { trigger_error('Bad Char in input 2', E_USER_ERROR); } $dezi = bcadd($dezi, bcmul(bcpow($quellformat, $i), $wert)); } if (10 == $zielformat) { return $vorzeichen . $dezi; // abkürzung } while (1 !== bccomp(bcpow($zielformat, $level++), $dezi)); for ($i = $level - 2; $i >= 0; $i--) { $factor = bcpow($zielformat, $i); $zahl = bcdiv($dezi, $factor, 0); $dezi = bcmod($dezi, $factor); $result .= $vorrat{$zahl}; } $result = empty($result) ? '0' : $result; return $vorzeichen . $result; } 

Can someone explain to me the above function or give me some lights about the process of direct conversion between arbitrary databases?

+7
math php base-conversion base62
source share
6 answers

Starting with PHP 5.3.2 and bc_math and gmp now support databases up to 62, so you can simply do:

 echo gmp_strval(gmp_init($mynumber, $srcbase), $destbase); 

or the equivalent of bc_math.

+12
source share

Please do not ask me where I got it from, I just remember that it is based on some examples that I found on the Internet ...

  function charset_base_convert ($numstring, $fromcharset, $tocharset) { $frombase=strlen($fromcharset); $tobase=strlen($tocharset); $chars = $fromcharset; $tostring = $tocharset; $length = strlen($numstring); $result = ''; for ($i = 0; $i < $length; $i++) { $number[$i] = strpos($chars, $numstring{$i}); } do { $divide = 0; $newlen = 0; for ($i = 0; $i < $length; $i++) { $divide = $divide * $frombase + $number[$i]; if ($divide >= $tobase) { $number[$newlen++] = (int)($divide / $tobase); $divide = $divide % $tobase; } elseif ($newlen > 0) { $number[$newlen++] = 0; } } $length = $newlen; $result = $tostring{$divide} . $result; } while ($newlen != 0); return $result; } 
+8
source share

The simplest approach for any translation task, from a numerical base to human languages, is to translate through an intermediate format.

 function bc_base_convert($num, $from, $to) { return bc_convert_to(bc_parse_num($num, $from), $to); } 

Now you need to write bc_convert_to and bc_parse_num . If the platform is distinguished by numerical types, you need to take this into account. In addition, floating point numbers require special consideration, because a number can have a finite representation in one base, but not another (for example, 1/3 is 0.1 3 , but 0.333 ... 10 , and 1/10 10 - .0001100110011 ... 2 ).

For a general explanation of how conversion works, consider how positional base systems work . The number of the form "a n a n-1 ... a 1 a 0 " in base b is the number "a n * b n + a n-1 * b n-1 + ... + a 1 * b 1 + a 0 * b 0 ". Conversion basically works by evaluating an expression in the context of another? Beta base.

+1
source share

Most of the examples I found on the Internet and in these answers use BC Math functions. If you do not want to use the BC Math functions, you can take a look at this library: http://www.lalit.org/lab/base62-php-convert-number-to-base-62-for-short-urls/

  • It does not use the BC Math functions, therefore it works without using the BC Math library.
  • It uses the base_convert native functions when the base is below 36 for faster execution.
  • The output number is backward compatible with the built-in base_convert function.
  • Can be used to convert to and from arbitrary databases between 2-64.
+1
source share

I wrote about using BCMath functions for decimal / binary conversion here: http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ . You can easily change this code to convert to different databases.

For example, if converting integers, change the procedures dec2bin_i () and bin2dec_i (). Rename them and add a basic parameter - something like dec2base_i ($ base, $ decimal_i) and base2dec_i ($ base, $ num_i), change hardcoded '2' to the $ base variable, convert the numeric residuals to / from the base characters and rename the variables .

Now, to convert between arbitrary bases, use the decimal number as an intermediate link and call both of these new functions. For example, convert base number 42 "123" to base 59 by calling $ dec = base2dec_i ('42 ',' 123 ') followed by $ b59 = dec2base_i (59, $ dec).

(You can also create a combined function that does this in one call.)

0
source share

This function outputs the same as GNU Multiple Precision , if possible ...

 <?php function base_convert_alt($val,$from_base,$to_base){ static $gmp; static $bc; static $gmp62; if ($from_base<37) $val=strtoupper($val); if ($gmp===null) $gmp=function_exists('gmp_init'); if ($gmp62===null) $gmp62=version_compare(PHP_VERSION,'5.3.2')>=0; if ($gmp && ($gmp62 or ($from_base<37 && $to_base<37))) return gmp_strval(gmp_init($val,$from_base),$to_base); if ($bc===null) $bc=function_exists('bcscale'); $range='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; if ($from_base==10) $base_10=$val; else { $n=strlen(($val="$val"))-++$ratio; if ($bc) for($i=$n;$i>-1;($ratio=bcmul($ratio,$from_base)) && $i--) $base_10=bcadd($base_10,bcmul(strpos($range,$val[$i]),$ratio)); else for($i=$n;$i>-1;($ratio*=$from_base) && $i--) $base_10+=strpos($range,$val[$i])*$ratio; } if ($bc) do $result.=$range[bcmod($base_10,$to_base)]; while(($base_10=bcdiv($base_10,$to_base))>=1); else do $result.=$range[$base_10%$to_base]; while(($base_10/=$to_base)>=1); return strrev($to_base<37?strtolower($result):$result); } echo base_convert_alt('2661500360',7,51); // Output Hello 
-one
source share

All Articles