PHP Doku:: Konvertiert einen numerischen Wert zwischen verschiedenen Zahlensystemen - function.base-convert.html

Verlauf / Chronik / History: (1) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzMathematische ErweiterungenMathematische FunktionenMathematische Funktionenbase_convert

Ein Service von Reinhard Neidl - Webprogrammierung.

Mathematische Funktionen

<<atanh

bindec>>

base_convert

(PHP 4, PHP 5)

base_convertKonvertiert einen numerischen Wert zwischen verschiedenen Zahlensystemen

Beschreibung

string base_convert ( string $number , int $frombase , int $tobase )

base_convert() wandelt einen im Zahlensystem zur Basis frombase codierten numerischen String number in die entsprechende Representation zur Basis tobase um. Sowohl formbase als auch tobase dürfen Werte zwischen 2 und 36 (inklusive) einnehmen. In Zahlensystemen mit einer Basis größer als Zehn werden die Ziffern größer als neun durch die Buchstaben a bis z representiert. A steht dabei für die 'Ziffer' 10, b für 11 und so weiter bis z für 35.

Warnung

base_convert() kann bei großen Werten auf Grund von Eigenschaften der zu Grunde liegenden internen "float"- und "double"-Datentypen die Genauigkeit verschlechtern. Sehen Sie hierzu bitte den Abschnitt Fließkommazahlen in diesem Handbuch für genauere Informationen zu diesem Thema.

Parameter-Liste

number

Die zu konvertierende numerische Zeichenkette

frombase

Die Basis zu der number kodiert ist

tobase

Die Basis zu der number konvertiert werden soll

Rückgabewerte

number konvertiert zur Basis tobase

Beispiele

Beispiel #1 base_convert() Beispiel

<?php
$hexadecimal 
'A37334';
echo 
base_convert($hexadecimal162);
?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

101000110111001100110100

Siehe auch

  • intval() - Konvertiert einen Wert nach integer


31 BenutzerBeiträge:
- Beiträge aktualisieren...
francesco[at]paladinux.net
23.09.2010 12:30
base convert is limited on standard base invented.
In some case, if you want to invented some translate code (for authorizion code 4 example) , I hope is usefull this example of base_convert-AS from decimal in 65imal base for a speedCode.
Some more specifical: you can transform using a db
$speedCodeDEC            = $idAziendaMittente.$idAziendaDestinatario.$idDDT ;

//$speedCodeDEC = 3000;

//
$BASECODE = array();
$BASECODE['items'] = 65;
$BASECODE[1]='1';
$BASECODE[2]='2';
$BASECODE[3]='3';
$BASECODE[4]='4';
....
$BASECODE[10]='a';
$BASECODE[11]='b';
$BASECODE[12]='c';
...
$BASECODE[36]='A';
$BASECODE[37]='B';
$BASECODE[38]='C';
...
$BASECODE[61]='Z';
$BASECODE[62]='/';
$BASECODE[63]='-';
$BASECODE[64]='+';
//

//print_r ($BASECODE);TEST

function creaSpeedCode ( $speedCodeDEC,$partialCode="",$BASECODE){

    @$division      = $speedCodeDEC/$BASECODE['items'];
    @$resultINT   = floor($speedCodeDEC/$BASECODE['items']);
    @$remnant          = $speedCodeDEC%$BASECODE['items'];
    $partialCode  = $BASECODE[$remnant].$partialCode;
echo "
    <br>
    Inserito speedCodeDEC:$speedCodeDEC - partialCode:$partialCode<br>
    items            : ".$BASECODE['items']."<br>
    division          : $division    <br>
    resultINT        : $resultINT    <br>
    remnant            : $remnant        <br>
    partialCode        : $partialCode    <br>
";//TEST   
    if ($resultINT > 65)     $partialCode = creaSpeedCode($resultINT,$partialCode,$BASECODE);
    return $BASECODE[$resultINT].$partialCode;
}
echo $speedCodeDEC."<br>";
echo $risultato = creaSpeedCode ( $speedCodeDEC,"",$BASECODE);
Tamas
19.02.2010 16:55
Another pair of functions to convert between numbers and their uppercase alphabet representation (A, B, ..., Z, AA, AB, ..., AZ, BA, BB, ..., BZ, CA, ..., ZZ, AAA, AAB, etc.)

<?php
/*
 * Convert an integer to a string of uppercase letters (A-Z, AA-ZZ, AAA-ZZZ, etc.)
 */
function num2alpha($n)
{
    for(
$r = ""; $n >= 0; $n = intval($n / 26) - 1)
       
$r = chr($n%26 + 0x41) . $r;
    return
$r;
}

/*
 * Convert a string of uppercase letters to an integer.
 */
function alpha2num($a)
{
   
$l = strlen($a);
   
$n = 0;
    for(
$i = 0; $i < $l; $i++)
       
$n = $n*26 + ord($a[$i]) - 0x40;
    return
$n-1;
}
?>
Theriault
30.11.2009 11:11
If you would like to convert numbers into just the uppercase alphabet base and vice-versa (e.g. the column names in a Microsoft Windows Excel sheet..A-Z, AA-ZZ, AAA-ZZZ, ...), the following functions will do this.

<?php

/**
 * Converts an integer into the alphabet base (A-Z).
 *
 * @param int $n This is the number to convert.
 * @return string The converted number.
 * @author Theriault
 *
 */
function num2alpha($n) {
   
$r = '';
    for (
$i = 1; $n >= 0 && $i < 10; $i++) {
       
$r = chr(0x41 + ($n % pow(26, $i) / pow(26, $i - 1))) . $r;
       
$n -= pow(26, $i);
    }
    return
$r;
}
/**
 * Converts an alphabetic string into an integer.
 *
 * @param int $n This is the number to convert.
 * @return string The converted number.
 * @author Theriault
 *
 */
function alpha2num($a) {
   
$r = 0;
   
$l = strlen($a);
    for (
$i = 0; $i < $l; $i++) {
       
$r += pow(26, $i) * (ord($a[$l - $i - 1]) - 0x40);
    }
    return
$r - 1;
}

?>

Microsoft Windows Excel stops at IV (255), but this function can handle much larger. However, English words will start to form after a while and some may be offensive, so be careful.
MFTM
16.08.2009 20:30
It might be a better function to deal with numbers over 9000. (even 10 millions)

<?php

function romanic_number($integer, $upcase = true)
{
   
$table = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1);
   
$return = '';
    while(
$integer > 0)
    {
        foreach(
$table as $rom=>$arb)
        {
            if(
$integer >= $arb)
            {
               
$integer -= $arb;
               
$return .= $rom;
                break;
            }
        }
    }

    return
$return;
}
?>
hamishcool3 at yahoo dot co dot uk
18.04.2009 9:47
I have a slight improvement on the roman numerals function:

<?php
function ar_rom($ar,$br="\r\n"){
   
$lin='';
   
$num='';
   
$rom=array(
        array(
'no'=>1000000, 'lin'=>'_', 'num'=>'M'),
        array(
'no'=>900000, 'lin'=>'_', 'num'=>'CM'),
        array(
'no'=>500000, 'lin'=>'_', 'num'=>'D'),
        array(
'no'=>400000, 'lin'=>'_', 'num'=>'CD'),
        array(
'no'=>100000, 'lin'=>'_', 'num'=>'C'),
        array(
'no'=>90000, 'lin'=>'_', 'num'=>'XC'),
        array(
'no'=>50000, 'lin'=>'_', 'num'=>'L'),
        array(
'no'=>40000, 'lin'=>'_', 'num'=>'XL'),
        array(
'no'=>10000, 'lin'=>'_', 'num'=>'X'),
        array(
'no'=>9000, 'lin'=>'_', 'num'=>'IX'),
        array(
'no'=>5000, 'lin'=>'_', 'num'=>'V'),
        array(
'no'=>4000, 'lin'=>'_', 'num'=>'IV'),
        array(
'no'=>1000, 'lin'=>' ', 'num'=>'M'),
        array(
'no'=>900, 'lin'=>' ', 'num'=>'CM'),
        array(
'no'=>500, 'lin'=>' ', 'num'=>'D'),
        array(
'no'=>400, 'lin'=>' ', 'num'=>'CD'),
        array(
'no'=>100, 'lin'=>' ', 'num'=>'C'),
        array(
'no'=>90, 'lin'=>' ', 'num'=>'XC'),
        array(
'no'=>50, 'lin'=>' ', 'num'=>'L'),
        array(
'no'=>40, 'lin'=>' ', 'num'=>'XL'),
        array(
'no'=>10, 'lin'=>' ', 'num'=>'X'),
        array(
'no'=>9, 'lin'=>' ', 'num'=>'IX'),
        array(
'no'=>5, 'lin'=>' ', 'num'=>'V'),
        array(
'no'=>4, 'lin'=>' ', 'num'=>'IV'),
        array(
'no'=>1, 'lin'=>' ', 'num'=>'I'),
    );
    foreach(
$rom as $k => $v){
        while(
$ar>=$v['no']){
           
$ar=$ar-$v['no'];
           
$lin.=$v['lin'];
           
$num.=$v['num'];
        }
    }
    if(
strpos($lin, '_')===FALSE){
        return
$num;
    }else{
        return
$lin.$br.$num;
    }
}

echo
ar_rom(1957938,'<br>');
?>

in browser returns:
____
MCMLVMMCMXXXVIII

(Line above = Number X 1000)

This is good for numbers up to about 10 million, otherwise you get:

______________________________________________
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM etc.

(normally the lines would be flush, if dealing with numbers over 3000 make sure to use Lucida Console or some other font where all the chars are the same length)
cyrilbele at yahoo dot fr
16.04.2009 10:58
If you want to do sharding, at some point you will need to decide which shard to target. Here is a simple function to assign the data to a particular shard based on a key (usually identifier of the row)

Here is a simple function to get the shard based on the key and the number of shards available

<?php
function getShard($key,$nbShards) {
   
$num = substr(base_convert(sha1($key), 16, 10),4,6);
    return
$num%$nbShards;
}
?>
mr-bungle sometimes uses TLEN.PL
6.08.2008 13:38
In response to "Ray Paseur sometimes uses GMail"

There is part of my class for specified operations on string etc.

I've written two methods to convert numbers between roman and arabic notation:

<?php

class Text
{
    public function
Arab2Roman($number)
    {
       
$out = '';

       
$translate = array(
                            array(
'arab' => 5000, 'roman' => ''),
                            array(
'arab' => 1000, 'roman' => 'M'),
                            array(
'arab' => 900, 'roman' => 'CM'),
                            array(
'arab' => 500, 'roman' => 'D'),
                            array(
'arab' => 400, 'roman' => 'CD'),
                            array(
'arab' => 100, 'roman' => 'C'),
                            array(
'arab' => 90, 'roman' => 'XC'),
                            array(
'arab' => 50, 'roman' => 'L'),
                            array(
'arab' => 40, 'roman' => 'XL'),
                            array(
'arab' => 10, 'roman' => 'X'),
                            array(
'arab' => 9, 'roman' => 'IX'),
                            array(
'arab' => 5, 'roman' => 'V'),
                            array(
'arab' => 4, 'roman' => 'IV'),
                            array(
'arab' => 1, 'roman' => 'I')
                            );

        if(
$number > $translate[0]['arab'])
           
$out = false;
        else
        {
           
$j = count($translate)-1;

            for(
$i=0;$i<$j;$i++)
            {
                if(
$number < $translate[$i]['arab'] && $number >= $translate[$i+1]['arab'])
                {
                   
$out .= $translate[$i+1]['roman'];
                   
$number -= $translate[$i+1]['arab'];

                    if(
$number)
                       
$out .= Text::Arab2Roman($number); // do it recursive until $numer is not 0

                   
break;
                }
            }
        }

        return (
$out);
    }

    public function
Roman2Arab($roman)
    {
       
$out = 0;
       
$translate = array(
                           
'M' => 1000,
                           
'D' => 500,
                           
'C' => 100,
                           
'L' => 50,
                           
'X' => 10,
                           
'V' => 5,
                           
'I' => 1
                           
);

       
$j = strlen($roman);

        for(
$i=0; $i<$j; $i++)
        {
           
$out += $translate[$roman[$i]];

           
// find wrong order of roman chars
           
if($i < $j-1 && $translate[$roman[$i]] < $translate[$roman[$i+1]])
            {
               
$out -= 2*$translate[$roman[$i]];
            }
        }

        return (
$out);
    }
}
?>
dorantor
14.05.2008 7:42
Spent almost a day to find a bug(?) in base_convert() function when converting big values to binary:

<?php
$value
= 2919739656537;
echo
base_convert($value, 10, 2);
?>
should print
101010011111001110000010111000100101011001
in reality, prints
10101000111000001100011100110101110110100100
but that is wrong!

so, in result, I've written this two functions:
<?php
/**
 * Convert binary to decimal
 * works with big numbers
 *
 * @param string $binary
 * @return float
 */
function big_bin2dec($binary)
{
   
$result = (float)0;

   
$shift = 0;
    while (
0 < strlen($binary) ) {
       
$bit    = substr($binary, -1);
       
$binary    = substr($binary, 0, -1);
       
$result = $result + $bit*pow(2, $shift);
        ++
$shift;
    }
    return
$result;
}

/**
 * convert decimal 2 binary presentation
 *
 * @param mixed $dec
 * @return string
 */
function big_dec2bin($dec)
{
   
$result    = '';
   
$shift    = 0;
    while (
pow(2, $shift) < $dec ) {
        ++
$shift;
    }
    while (
0 <= $shift ) {
       
$pow = pow(2, $shift);
        if (
$pow <= $dec ) {
           
$dec-= $pow;
           
$result = $result . '1';
        } else {
           
$result = $result . '0';
        }
        --
$shift;
    }
    return
$result;
}
?>
Functions tested only with positive integers(that's enough for me), so if you need more than this you'll, possibly, have to rework 'em.

Simple test:
<?php
$value
= pow(2, 48);//only one bit should be set

printf("%f \n", $value);
echo
base_convert($value, 10, 2), "\n";
echo
big_dec2bin($value), "\n";
?>
prints out something similar to:
281474976710656.000000
110011001100110011001100110011001100111001010
1000000000000000000000000000000000000000000000000

I hope this will help someone :)
BTW! My phpinfo() says PHP Version 5.2.1
Todd Stokes @ Georgia Tech
21.11.2007 1:37
I wrote a function to fix the problem stated above about floating point numbers. (this is especially useful for arithmetic coding, which is what I'm working on) It's not tremendously robust, but it gets the job done for "simple" float values.

function floatbin($myfloat, $precision=16, $return_int_part=true) {

        //echo "complete: $myfloat\n";
        $binary_string = "";
        if($return_int_part) {
                $binary_string = decbin($myfloat);
                $binary_string .= ".";
                $fractional_part = $myfloat-intval($myfloat);
        } else {
                $fractional_part = explode(".",$myfloat);
                $fractional_part = ".".$fractional_part[1];
        }
        //echo "fractional: $fractional_part\n";

        for ($i=1; $i < $precision+1; $i++) {
                $binary_fraction = 1/pow(2,$i);
                if($fractional_part >= $binary_fraction) {
                        $binary_string .= "1";
                        $fractional_part = $fractional_part - $binary_fraction;
                } else {
                        $binary_string .= "0";
                }
                if($fractional_part == 0) {
                        break;
                }
                //echo "order: $binary_fraction\t\t";
                //echo "state: $fractional_part\n";
        }

        return $binary_string;

}

// no problem
$myfloat = 1.5;
$decfloat = base_convert($myfloat,10,2);
echo "result: $decfloat\n"; // returns 1111 (wrong)
$decfloat = floatbin($myfloat, 32);
echo "result: $decfloat\n"; // returns 1.1 (correct)
$decfloat = floatbin($myfloat,16,false);
echo "result: $decfloat\n"; // returns 1 (correct)

// no problem
$myfloat = 4.125;
$decfloat = base_convert($myfloat,10,2);
echo "result: $decfloat\n"; // returns 1000000011101 (wrong)
$decfloat = floatbin($myfloat, 32);
echo "result: $decfloat\n"; // returns 100.001 (correct)
$decfloat = floatbin($myfloat,16,false);
echo "result: $decfloat\n"; // returns 001 (correct)

// will be truncated, so the inverse will not be ==
$myfloat = 12.3456;
$decfloat = base_convert($myfloat,10,2);
echo "result: $decfloat\n"; // returns 11110001001000000 (wrong)
$decfloat = floatbin($myfloat, 32);
echo "result: $decfloat\n"; // returns 1100.01011000011110010011110111011001 (correct, truncated)
$decfloat = floatbin($myfloat,16,false);
echo "result: $decfloat\n"; // returns 0101100001111001 (correct, truncated more)

// a case on where passing false is useful, so the inverse will not be ==
$myfloat = 777777777777.777777;
$decfloat = base_convert($myfloat,10,2);
echo "result: $decfloat\n"; // wrong
$decfloat = floatbin($myfloat, 32);
echo "result: $decfloat\n"; // wrong
$decfloat = floatbin($myfloat,16,false);
echo "result: $decfloat\n"; // correct, but truncated
CFK
14.02.2007 14:07
Here is the function made by David Leppek who works in both way :

<?php
function big_convert ($number,$to_base) {
   
$result = "";
    switch (
$to_base) {
    case
"2":
       
$temp = preg_split('//', $number, -1, PREG_SPLIT_DELIM_CAPTURE);
       
$lng = strlen($number);
        for (
$i = 1;$i <= $lng;$i++) { $result .= str_pad(base_convert($temp[$i], 16, 2), 4, '0', STR_PAD_LEFT); }
        return
$result;
    break;

    case
"16":
       
$bin = substr(chunk_split (strrev($number), 4,'-'), 0, -1);
       
$temp = preg_split('[-]', $bin, -1, PREG_SPLIT_DELIM_CAPTURE);
        for (
$i = count($temp)-1;$i >= 0;$i--) { $result = $result . base_convert(strrev($temp[$i]), 2, 16); }
        return
strtoupper($result);
    break;
    }
}

$bin = "1011010011110010100100101011011101100101001101001111";
echo
$hex = big_convert ($bin,16);
echo
big_convert ($hex,2);
?>
Ray Paseur sometimes uses GMail
7.12.2006 0:55
function roman_numerals($input_arabic_numeral='') {

    if ($input_arabic_numeral == '') { $input_arabic_numeral = date("Y"); } // DEFAULT OUTPUT: THIS YEAR
    $arabic_numeral            = intval($input_arabic_numeral);
    $arabic_numeral_text    = "$arabic_numeral";
    $arabic_numeral_length    = strlen($arabic_numeral_text);

    if (!ereg('[0-9]', $arabic_numeral_text)) {
return false; }

    if ($arabic_numeral > 4999) {
return false; }

    if ($arabic_numeral < 1) {
return false; }

    if ($arabic_numeral_length > 4) {
return false; }

    $roman_numeral_units    = $roman_numeral_tens        = $roman_numeral_hundreds        = $roman_numeral_thousands        = array();
    $roman_numeral_units[0]    = $roman_numeral_tens[0]    = $roman_numeral_hundreds[0]    = $roman_numeral_thousands[0]    = ''; // NO ZEROS IN ROMAN NUMERALS

    $roman_numeral_units[1]='I';
    $roman_numeral_units[2]='II';
    $roman_numeral_units[3]='III';
    $roman_numeral_units[4]='IV';
    $roman_numeral_units[5]='V';
    $roman_numeral_units[6]='VI';
    $roman_numeral_units[7]='VII';
    $roman_numeral_units[8]='VIII';
    $roman_numeral_units[9]='IX';

    $roman_numeral_tens[1]='X';
    $roman_numeral_tens[2]='XX';
    $roman_numeral_tens[3]='XXX';
    $roman_numeral_tens[4]='XL';
    $roman_numeral_tens[5]='L';
    $roman_numeral_tens[6]='LX';
    $roman_numeral_tens[7]='LXX';
    $roman_numeral_tens[8]='LXXX';
    $roman_numeral_tens[9]='XC';

    $roman_numeral_hundreds[1]='C';
    $roman_numeral_hundreds[2]='CC';
    $roman_numeral_hundreds[3]='CCC';
    $roman_numeral_hundreds[4]='CD';
    $roman_numeral_hundreds[5]='D';
    $roman_numeral_hundreds[6]='DC';
    $roman_numeral_hundreds[7]='DCC';
    $roman_numeral_hundreds[8]='DCCC';
    $roman_numeral_hundreds[9]='CM';

    $roman_numeral_thousands[1]='M';
    $roman_numeral_thousands[2]='MM';
    $roman_numeral_thousands[3]='MMM';
    $roman_numeral_thousands[4]='MMMM';

    if ($arabic_numeral_length == 3) { $arabic_numeral_text = "0" . $arabic_numeral_text; }
    if ($arabic_numeral_length == 2) { $arabic_numeral_text = "00" . $arabic_numeral_text; }
    if ($arabic_numeral_length == 1) { $arabic_numeral_text = "000" . $arabic_numeral_text; }

    $anu = substr($arabic_numeral_text, 3, 1);
    $anx = substr($arabic_numeral_text, 2, 1);
    $anc = substr($arabic_numeral_text, 1, 1);
    $anm = substr($arabic_numeral_text, 0, 1);

    $roman_numeral_text = $roman_numeral_thousands[$anm] . $roman_numeral_hundreds[$anc] . $roman_numeral_tens[$anx] . $roman_numeral_units[$anu];
return ($roman_numeral_text);
}
Kiam
12.08.2006 14:07
Refering to the function posted by Michael Renner, I would change the line
  $result = $tostring{$divide} . $result;
in
  $result = $chars{$divide} . $result;
as $divide seems garanted to be less than $tobase.
That also eliminates the need of the variable $tostring.

-- Kiam
Michael Renner
17.05.2006 15:24
Here is an unfucked version of the arbitrary-large-number base_convert examples below:

I modified it so that it works as drop-in replacement for base_convert. Attention, no sanity checking is done for the input numbers, anything larger than 36 won't work..

function unfucked_base_convert ($numstring, $frombase, $tobase) {

   $chars = "0123456789abcdefghijklmnopqrstuvwxyz";
   $tostring = substr($chars, 0, $tobase);

   $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;
}
CJ Dennis
6.04.2006 10:03
Really huge numbers might be truncated at both ends.
eg:
<?php
$binary
="11010101001111010001110101000100011110010110110".
"001111000010001010001111001100011010110110010010011010".
"001011010000001001011111110001010101101101011010101010".
"000100011101110010110010100111110001010010111010110011".
"001111111100011001011011001110001111110000101011010010";
print(
strtoupper(base_convert($binary, 2, 16)));
?>
will output:
9E8EA23CB63C0000000000000000000000000000000000000000000000000000 (64 hex digits)
when the correct result would be:
6A9E8EA23CB63C228F31AD9268B4097F156D6AA11DCB29F14BACCFF196CE3F0AD2 (66 hex digits)
Notice that as well as the result showing '0's after B63C which you would expect it is also missing the first 6A before 9E.
david dot leppek at paybytouch dot com
17.11.2005 16:54
I was working on an application that needed to convert a 16 digit HEX number to BINARY.  base_convert was choking when the binary number exceeded 54 characters.

$hex_value    = B76ADDCE71CCC6BE;
$Sample    = base_convert ($hex_value, 16, 2);
print $Sample;       

//printed: 1011011101101010110111011100111001110001110011001100100000000000

Reviewing the examples here, I didnt find anything that worked for my exact need.  Here is what I came up with:

function big_convert($string_in, $hex, $bin){
$temp=preg_split('//',$string_in,-1,PREG_SPLIT_DELIM_CAPTURE);
for($i=1;$i< strlen($string_in)+1; $i++) {
$results .= str_pad(base_convert($temp[$i], $hex, $bin), 4, '0', STR_PAD_LEFT);
}
return $results;
}

$hex_value    = B76ADDCE71CCC6BE;
$Sample    = big_convert ($hex_value, 16, 2);
print $Sample;   

//printed: 1011011101101010110111011100111001110001110011001100011010111110

Hope this helps...  David Leppek
rithiur at mbnet dot fi
27.07.2005 17:23
Here is a simple function that works like the function provided by Mr. Fips (See below) with the exception that this can convert numbers of any size. However, note that as the division is performed manually to the number, this function is not very efficient and may not be suitable for converting strings with more than a few hundred numbers (depending on the number bases).

<?php
function custombase_convert_big ($numstring, $frombase, $tobase)
{
   
$from_count = strlen($frombase);
   
$to_count = strlen($tobase);
   
$length = strlen($numstring);
   
$result = '';
    for (
$i = 0; $i < $length; $i++)
    {
       
$number[$i] = strpos($frombase, $numstring{$i});
    }
    do
// Loop until whole number is converted
   
{
       
$divide = 0;
       
$newlen = 0;
        for (
$i = 0; $i < $length; $i++) // Perform division manually (which is why this works with big numbers)
       
{
           
$divide = $divide * $from_count + $number[$i];
            if (
$divide >= $to_count)
            {
               
$number[$newlen++] = (int)($divide / $to_count);
               
$divide = $divide % $to_count;
            }
            elseif (
$newlen > 0)
            {
               
$number[$newlen++] = 0;
            }
        }
       
$length = $newlen;
       
$result = $tobase{$divide} . $result; // Divide is basically $numstring % $to_count (i.e. the new character)
   
}
    while (
$newlen != 0);
    return
$result;
}

$HEX = "0123456789ABCDEF";
$DEC = "0123456789";
print
custombase_convert_big ("FFFFFF", $HEX, $DEC); // Prints "16777215"

$BIN = "01";
$ASCII = "";
for (
$i = 0; $i < 256; $i++)
{
   
$ASCII .= chr($i);
}
$msg = "0100100101110100001000000101011101101111011100100110101101110011";
print
custombase_convert_big($msg, $BIN, $ASCII); // Prints "It Works"

?>
fragmer[at]mail[dot]ru
2.05.2005 5:58
Here is a much simpler and faster version of the "custombase_convert" function proposed by Mr.Fips (see below). My functions convert decimals to and from custom bases:

<?php
// Decimal > Custom
function dec2any( $num, $base=62, $index=false ) {
    if (!
$base ) {
       
$base = strlen( $index );
    } else if (!
$index ) {
       
$index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base );
    }
   
$out = "";
    for (
$t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {
       
$a = floor( $num / pow( $base, $t ) );
       
$out = $out . substr( $index, $a, 1 );
       
$num = $num - ( $a * pow( $base, $t ) );
    }
    return
$out;
}
?>
Parameters:
$num - your decimal integer
$base - base to which you wish to convert $num (leave it 0 if you are providing $index or omit if you're using default (62))
$index - if you wish to use the default list of digits (0-1a-zA-Z), omit this option, otherwise provide a string (ex.: "zyxwvu")

<?php
// Custom > Decimal
function any2dec( $num, $base=62, $index=false ) {
    if (!
$base ) {
       
$base = strlen( $index );
    } else if (!
$index ) {
       
$index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );
    }
   
$out = 0;
   
$len = strlen( $num ) - 1;
    for (
$t = 0; $t <= $len; $t++ ) {
       
$out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
    }
    return
$out;
}
?>
Parameters:
$num - your custom-based number (string) (ex.: "11011101")
$base - base with which $num was encoded (leave it 0 if you are providing $index or omit if you're using default (62))
$index - if you wish to use the default list of digits (0-1a-zA-Z), omit this option, otherwise provide a string (ex.: "abcdef")

I have optimized the functions as much as I could, I hope they'll be helpful to someone.
lindsay at bitleap dot com
18.03.2005 22:17
If you need to use base_convert with numbers larger then 32 bit, the following gmp implementation of base_convert should work.

<?php

/*use gmp library to convert base. gmp will convert numbers > 32bit*/
function gmp_convert($num, $base_a, $base_b)
{
        return
gmp_strval ( gmp_init($num, $base_a), $base_b );
}

?>
tomhiggy at gmail dot com
16.03.2005 12:28
I was looking for a function to convert the base encoding of a sha1 hash from base 16 to a custom base 32 (using characters [A-Z2-7], as used by several filesharing applications).

The function custombase_convert() posted by Fips isn't able to cope with numbers above a certain value. It returns the first few (around 10) characters correctly but each character after is a 0 value ('A' in this case).

I've solved the problem for now by requesting in groups of 10 base 16 characters and appending the result to the final base 32 value. If anyone has any better solutions, please let me know.
mike at we cant lose dot com
14.02.2005 6:52
There are a few functions posted here to inverse or invert a hex color code yet none of them have actually worked for me.

This function will take a hex color code string such as '#00FF00' and return the inversed or inverted hex color code string of '#FF00FF'.

<?

function inverseColor($hex) {
    if(
substr($hex, 0, 1) == '#') $hex = substr($hex, 1);
   
   
$r = str_pad(dechex(255 - hexdec(substr($hex, 0, 2)) ),2,'0',STR_PAD_LEFT);
   
$g = str_pad(dechex(255 - hexdec(substr($hex, 2, 2)) ),2,'0',STR_PAD_LEFT);
   
$b = str_pad(dechex(255 - hexdec(substr($hex, 4, 2)) ),2,'0',STR_PAD_LEFT);

    return
strtoupper('#'.$r.$g.$b);   
}

?>
simon at simonster dot com
16.06.2004 3:05
Here are some functions for converting integers to and from base 256. Converting to base 64 is simple given these.

<?php
function to_base256($number, $from_base = 10) {
   
$binary_number = base_convert($number, $from_base, 2);
   
$final_string = "";
   
$new_length = (ceil(strlen($binary_number)/8)*8);
   
$binary_number = str_pad($binary_number, $new_length, "0", STR_PAD_LEFT);
    for(
$i=($new_length-8); $i>=0; $i-=8) {
       
$final_string = chr(base_convert(substr($binary_number, $i, 8), 2, 10)).$final_string;
    }
    return
$final_string;
}

function
from_base256($string, $to_base = 10) {
   
$number = "";
    for(
$i=0; $i<strlen($string); $i++) {
       
$number .= str_pad(base_convert(ord($string{$i}), 10, 2), 8, "0", STR_PAD_LEFT);
    }
    return
base_convert($number, 2, $to_base);
}
?>

Yes, I know that this would be more efficient if it used mod instead of base_convert, but it needs to work with integers > 32 bits.
AdamJacobMuller at AdamJacobMuller dot com
28.04.2004 23:20
<?php
function binarycodedstring2dec($binary) {
       
$len=strlen($binary);
       
$rows=($len/4)-1;
        if ((
$len%4)>0) {
               
$pad=$len+(4-($len%4));
               
$binary=str_pad($binary,$pad,"0",STR_PAD_LEFT);
               
$len=strlen($binary);
               
$rows=($len/4)-1;
        }
       
$x=0;
        for (
$x=0;$x<=$rows;$x++) {
               
$s=($x*4);
               
$bins=$binary[$s].$binary[$s+1].$binary[$s+2].$binary[$s+3];
               
$num=base_convert($bins,2,10);
                if (
$num>9) {
                        die(
"the string is not a proper binary coded decimal\n");
                } else {
                       
$res.=$num;
                }
        }
        return
$res;
}
?>

a binary coded decimal is converted by taking groups of four from a decimal string,
for example the binary coded decimal string
1000 = 8
10001000 does not = 136 but 88
so
binarycodedstring2dec(1000) = 8
binarycodedstring2dec(11100000111001)=3839
binarycodedstring2dec(100000111001)=839

i truly have no idea if this function will be useful to anyone, i simply failed a physics midterm because i didn't know this so i wrote this function to make sure i would never forget how to convert binary coded decimals
Matt AKA Junkie
24.04.2004 10:11
You seem to not see the simplicity of using assembly-esque ideals when inverting colors...

<?
// precond: $color is a hex integer
// postcond: returns inversion
function InvertColor($color)
{
  return (int)
0xffffff - $color;
}
?>
kx
25.03.2004 22:06
There's an useful function custombase_convert(), which seems to be very useful, for example, to implement genealogical trees model proposed by Miguel Sofer (http://darwin.zoology.gla.ac.uk/~rpage/ MyToL/www/downloads/trees.pdf). Unfortunately, Fips' code has a bug. To make it work correctly you should replace line
       while ($decVal > 0)
with this:
       while ($decVal > 0 || $pos >=0)
hkh at netnords dot dk
26.02.2004 18:36
An optimized version of fiftytoo InvertColor() function.

<?php
function InvertColor($hex)
{
  return
sprintf("%06X", $hex ^ 0xFFFFFF);
}
?>
fiftytoo at buckeyeexpress dot com
24.12.2003 9:57
I needed a function to invert a hex value, which i used for setting font colors when they were on a colored background, that way i will get a contrasting color.

Im sure there are other reasons to use this, you decide!!

<?php
function InvertColor($hex) {
  return
sprintf("%06s",base_convert(($hex ^ 0xFFFFFF),10,16));
  };

print
'<td bgcolor="BB2222"><font color="'.InvertColor(0xBB2222).'">Blah</font></td>';
// Prints 44dddd as the font color, which is it's opposite on the color wheel

?>
Fips
29.07.2003 20:08
I wrote a function for converting numbers not only into 0-9 and a-z:

-----
<?php
function custombase_convert($numstring, $baseFrom = "0123456789", $baseTo = "0123456789")
{
   
$numstring = (string) $numstring;
   
$baseFromLen = strlen($baseFrom);
   
$baseToLen = strlen($baseTo);
    if (
$baseFrom == "0123456789") // No analyzing needed, because $numstring is already decimal
   
{
       
$decVal = (int) $numstring;
    } else {
       
$decVal = 0;
        for (
$len = (strlen($numstring) - 1); $len >= 0; $len--)
        {
           
$char = substr($numstring, 0, 1);
           
$pos = strpos($baseFrom, $char);
            if (
$pos !== FALSE)
            {
               
$decVal += $pos * ($len > 0 ? pow($baseFromLen, $len) : 1);
            }
           
$numstring = substr($numstring, 1);
        }
    }
    if (
$baseTo == "0123456789") // No converting needed, because $numstring needs to be converted to decimal
   
{
       
$numstring = (string) $decVal;
    } else {
       
$numstring = FALSE;
       
$nslen = 0;
       
$pos = 1;
        while (
$decVal > 0)
        {
           
$valPerChar = pow($baseToLen, $pos);
           
$curChar = floor($decVal / $valPerChar);
            if (
$curChar >= $baseToLen)
            {
               
$pos++;
            } else {
               
$decVal -= ($curChar * $valPerChar);
                if (
$numstring === FALSE)
                {
                   
$numstring = str_repeat($baseTo{1}, $pos);
                   
$nslen = $pos;
                }
               
$numstring = substr($numstring, 0, ($nslen - $pos)) . $baseTo{$curChar} . substr($numstring, (($nslen - $pos) + 1));
               
$pos--;
            }
        }
        if (
$numstring === FALSE) $numstring = $baseTo{1};
    }
    return
$numstring;
}
?>
------

The function arguments:
$numstring - String with number to convert. (e.g. "15" or "5F")
$baseFrom - Chars of the base the number is in. (e.g. "0123456789" for decimal or "01" for binary)
$baseTo - Chars of the base to convert the number. (e.g. "0123456789" for decimal or "01" for binary)

I wrote it for writing numbers in files, and so I convert between "0123456789" (decimal) and "\x01\x02\x03...\xFF" - uses very low disc space :-) (You could of course also add the null char (\x00), but >I< need it to seperate the numbers)
sam_at_compasspointmedia.com
7.12.2002 11:15
If you haven't already figured it out from the text, the higest base you can encode in is 36 (because z is 35),  try this

<?php
$compactIt
= base_convert('999',10,37);  //or anything higher
?>

and you'll get a warning.
gateschris at yahoo dot com
27.03.2001 2:57
if your worried about little/big edian affecting your dec to binary conversions, or just want to convert large numbers then try this bit of code:
<?
// this little bit of code is simply to convert a 64bit number.
function convert_num ($value) {
 
$value = (string) $value;
 while (!
preg_match('/^0*$/', $value) && $j < 65) {
 
$cumulate = '';
 
$rem = '';
  for (
$i = 0; $i < strlen($value); $i++) {
   if (
$cumulate == '') {
    if (
floor(($value[$i] + $rem) / 2)) {
    
$cumulate .= floor(($value[$i] + $rem) / 2);
    }
   } else {
   
$cumulate .= floor(($value[$i] + $rem) / 2);
   }
  
$rem = $value [$i] % 2 * 10;
  }
 
$r = floor($rem / 10);
 
$re .= $r;
 
$value = $cumulate;
 
$j++;
 }  
 return
$re;
}

print
convert_num (65535);
?>
tim_converse at yahoo dot com
20.01.2000 0:24
base_convert expects its string arguments to be integral, and gives nonsensical answers when given floating-point strings.  For example, base_convert("1.0", 10, 2) yields "1100100".  It seems that "1.0" is being interpreted as "100".  (PHP4.0b3).
scott at mha dot ca
9.09.1999 0:48
This would seem to be limited to 31 bits, ie. the range of values that can be converted is 0 - 2147483647 in decimal.

Also, this will convert negative values to positive values, unlike DecHex() which will return a null string for negative values.

From what I have observed (using PHP 3.0.11) the following statements will set both a and c to a null string and set b to positive 1.

<?php
$a
= base_convert (2147483648, 10, 16);
$b = base_convert (-1, 10, 16);
$c = dechex (-1);
?>



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)