Convertions between decimal and base 36
Asked Answered
C

2

5

I want to convert numbers in base 36 using PHP. The function base_convert is not working because I want to convert large numbers: I don't get my initial number if I convert it again from base 36 to decimal.

I tried some function given on multiple websites, but I never get the same result. Also, these two websites (in Javascript) give the same result:

For example 1010701001118000000000000000 has to be converted to 3IZS0ZE1RQ68W8SSW4.

Here are the functions I tried (and which don't work):

Chairborne answered 6/5, 2012 at 16:2 Comment(4)
why not convert your number to string and then encode with base64?Lubbi
The idea is to reduce the length of the number.Chairborne
Do you need to convert the number back to decimal at some point?Therewith
Yes I do, the number in base 36 is just here to be exchanged, I need to get it in decimal at the end (whithout knowing the function used to convert in base 36).Chairborne
T
10

Here are two simple functions using an algorithm found on Wikipedia, while using bcmath to get the calculations even for very large numbers right:

function fromDecimalToBase($in, $to) {
    $in = (string) $in;
    $out = '';

    for ($i = strlen($in) - 1; $i >= 0; $i--) {
        $out = base_convert(bcmod($in, $to), 10, $to) . $out;
        $in = bcdiv($in, $to);
    }

    return preg_replace('/^0+/', '', $out);
}

function fromBaseToDecimal($in, $from) {
    $in = (string) $in;
    $out = '';

    for ($i = 0, $l = strlen($in); $i < $l; $i++) {
        $x = base_convert(substr($in, $i, 1), $from, 10);
        $out = bcadd(bcmul($out, $from), $x);
    }

    return preg_replace('/^0+/', '', $out);
}

However, I get 3izs0ze1rq66tifrpc for the number you've provided - maybe your conversion was wrong there?

Therewith answered 6/5, 2012 at 16:40 Comment(4)
You get the same result as the other answer, maybe the Javascript converters are wrong... But I don't know how to find out. I may have to find a "perfect" converter to know...Chairborne
@Chairborne I've added the conversion back to decimal, and it seems to work so far.Therewith
But, I can use only the first one and just swap $from and $to :). Whatever, I see that you use the PHP function base_convert, so I think your conversion is the right one. I'll accept your answer, thanks!Chairborne
The difference between the two functions is mainly, that the first one computes % and / in the source-system while the second one computes + and * in the target-system. Since bcmath can only handle decimal numbers, you will need to use the first one to get from decimal to any other base (so that "decimal" is the source-system) and the second one to get from any base back to decimal ("decimal" = target-system).Therewith
B
3

http://www.pgregg.com/projects/php/base_conversion/base_conversion.php

This page show you how to convert arbitrary length numbers between different bases. I tried your example and it looks like it works in both directions. Source code written in PHP is available.

Boggart answered 6/5, 2012 at 16:23 Comment(1)
I don't know which code is right, but with your link, I get 3IZS0ZE1RQ66TIFRPC instead of 3IZS0ZE1RQ68W8SSW4Chairborne

© 2022 - 2024 — McMap. All rights reserved.