文字

base_convert

(PHP 4, PHP 5)

base_convert在任意进制之间转换数字

说明

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

返回一字符串,包含 numbertobase 进制的表示。number 本身的进制由 frombase 指定。frombasetobase 都只能在 2 和 36 之间(包括 2 和 36)。高于十进制的数字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。

Warning

由于使用内部的 "double" 或 "float" 类型, base_convert() 的操作可能会导致大数值中的精度丢失。请参见本手册的 浮点数 章节以便获得更多详细信息。

参数

number

要转换的数字

frombase

The base number is in

tobase

The base to convert number to

返回值

number converted to base tobase

范例

Example #1 base_convert() 例子

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

以上例程会输出:

101000110111001100110100

参见

  • intval() - 获取变量的整数值

用户评论:

[#1] liams dot test dot acc at gmail dot com [2015-08-16 22:49:34]

I wrote this as part of a college assignment to shorten urls. It works for any base and with any range of characters, eg. A-Za-z0-9 etc. Hope it helps someone.

<?php

        $base = range(0, 1);
        $number = 255;

        function translate($base, $number){

                $array = array();
                $n = count($base);
                $i = $number;

                while(true){

                
                        
                        if($i <= 0){

                                break;
                        }else{
                                $r = ($i % $n);

                              //reassign the value of $i
                                $i = ($i - $r) / $n;

                                $array[] = $base[$r];
                        }
                }
                $string = implode("", $array);
                return $string;
        } 

        $string = translate($base, $number);
        echo $string;
        
        // prints 11111111
?

[#2] ardavies at tiscali dot co dot uk [2014-05-24 11:31:03]

In order to convert base 26 (hexavigesimal) of just alphanumeric characters (A-Z), wthout integers, (as descibed at http://en.wikipedia.org/wiki/Hexavigesimal), I found this to be useful:

function base_convert_alpha(  $str,  $from,  $to  )
{
$r = range( 'A', 'Z' );
$clean = str_replace( $r, array_keys($r), $str );
return base_convert( $clean, $from, $to );
}

echo base_convert_alpha(  "BAC",  26,  10  );

//$clean = 102 which then returns 678

[#3] andrew at youritland dot co dot uk [2014-04-29 15:49:54]

Example of using base_convert to generate random passwords

function random_password()
{
  $rvalue1 = mt_rand(100,999);
  $rvalue2 = time();
  $rvalue3 = mt_rand(1000,9999);
  $rvalue4 = mt_rand(1,9);
  $rvalue5 = mt_rand(101,109);
  //combine values
  $rvalues = intval(((($rvalue2.$rvalue3) + $rvalue1)*$rvalue4) / $rvalue5);
  
  //return value in base-35 (will contain chars from '0' to 'z')
  return base_convert($rvalues,10,35);
}

Change the range of rvalue5 to get more or less characters. This setting
will return 8 chars.

[#4] Korkman [2013-10-09 11:10:22]

A word of warning to those copying the custombase_convert function from Fips: it's buggy. Converting decimal 16 to hex gives "1", should be "10". Do not use.

[#5] denik dot od at gmail dot com [2013-06-07 14:55:20]

Convert any length bits to HEX:

function bits2hex($bin)
{
   $out = "";
   for($i=0;$i<strlen($bin);$i+=8)
   {
      $byte = substr($bin,$i,8); if( strlen($byte)<8 ) $byte .= str_repeat('0',8-strlen($byte));
      $out .= base_convert($byte,2,16);
   }
   return $out;
}

VARNING! If the last byte is incomplete, it is supplemented with zeros as string!

[#6] Clifford dot ct at gmail dot com [2012-08-07 02:01:50]

If you use base_convert to convert a large (eg. 80-bit) hexadecimal to base-36, you might observe:

ABCDEF00001234567890 (hexadecimal) => 3O47RE02JZSW0KS8 (base-36) => ABCDEF00001240000000 (hexadecimal)

This is normal and is due to the loss of precision on large numbers.

I have written a string-based function using the built-in BC Math Extension which will overcome this and similar problems.

<?php

function str_baseconvert($str$frombase=10$tobase=36) {
    
$str trim($str);
    if (
intval($frombase) != 10) {
        
$len strlen($str);
        
$q 0;
        for (
$i=0$i<$len$i++) {
            
$r base_convert($str[$i], $frombase10);
            
$q bcadd(bcmul($q$frombase), $r);
        }
    }
    else 
$q $str;
 
    if (
intval($tobase) != 10) {
        
$s '';
        while (
bccomp($q'0'0) > 0) {
            
$r intval(bcmod($q$tobase));
            
$s base_convert($r10$tobase) . $s;
            
$q bcdiv($q$tobase0);
        }
    }
    else 
$s $q;
 
    return 
$s;
}

?>


Typical use-cases:
1.  Convert a large arbitrary precision number to base-36.
2.  Convert a 32-char hexadecimal UUID (128-bit) to a 25-char base-36 unique key, and vice versa.

Examples:

<?php
$b16 
'ABCDEF00001234567890';
$b36 str_baseconvert($b161636);
echo (
"$b16 (hexadecimal) = $b36 (base-36) \\n");

$uuid 'ABCDEF01234567890123456789ABCDEF';
$ukey str_baseconvert($uuid1636);
echo (
"$uuid (hexadecimal) = $ukey (base-36) \\n");
?>


ABCDEF00001234567890 (hexadecimal) = 3o47re02jzqisvio (base-36) 
ABCDEF01234567890123456789ABCDEF (hexadecimal) = a65xa07491kf5zyfpvbo76g33 (base-36)

[#7] Baji dot Panchumarti at gmail dot com [2012-07-04 19:50:03]

Extending base_convert to bases above 36, up to base 62.

<?php
function base_convert_x$_number=''$_frBase=10$_toBase=62 ) {

#   Today's Date - C74 - convert a string (+ve integer) from any arbitrary base to any arbitrary base, up to base 62, using  0-9,A-Z,a-z
#
#   Usage :   echo base_convert_x( 123456789012345, 10, 32 );

  
$_10to62 =  array(
    
'0'  => '0''1'  => '1''2'  => '2''3'  => '3''4'  => '4''5'  => '5''6'  => '6''7'  => '7''8'  => '8''9'  => '9''00' => '0''01' => '1''02' => '2''03' => '3''04' => '4''05' => '5''06' => '6''07' => '7',
    
'10' => 'A''11' => 'B''12' => 'C''13' => 'D''14' => 'E''15' => 'F''16' => 'G''17' => 'H''18' => 'I''19' => 'J''20' => 'K''21' => 'L''22' => 'M''23' => 'N''24' => 'O''25' => 'P''26' => 'Q''27' => 'R',
    
'30' => 'U''31' => 'V''32' => 'W''33' => 'X''34' => 'Y''35' => 'Z''36' => 'a''37' => 'b''38' => 'c''39' => 'd''40' => 'e''41' => 'f''42' => 'g''43' => 'h''44' => 'i''45' => 'j''46' => 'k''47' => 'l',
    
'50' => 'o''51' => 'p''52' => 'q''53' => 'r''54' => 's''55' => 't''56' => 'u''57' => 'v''58' => 'w''59' => 'x''60' => 'y''61' => 'z'  );

  
$_62to10 =  array(
    
'0' => '00''1' => '01''2' => '02''3' => '03''4' => '04''5' => '05''6' => '06''7' => '07''8' => '08''9' => '09''A' => '10''B' => '11''C' => '12''D' => '13''E' => '14''F' => '15''G' => '16''H' => '17',
    
'K' => '20''L' => '21''M' => '22''N' => '23''O' => '24''P' => '25''Q' => '26''R' => '27''S' => '28''T' => '29''U' => '30''V' => '31''W' => '32''X' => '33''Y' => '34''Z' => '35''a' => '36''b' => '37',
    
'e' => '40''f' => '41''g' => '42''h' => '43''i' => '44''j' => '45''k' => '46''l' => '47''m' => '48''n' => '49''o' => '50''p' => '51''q' => '52''r' => '53''s' => '54''t' => '55''u' => '56''v' => '57',
    
'y' => '60''z' => '61' );

#   ---- First convert from frBase to base-10

    
$_in_b10        =   0;
    
$_pwr_of_frB    =   1;                        #  power of from base, eg. 1, 8, 64, 512
    
$_chars         =   str_split$_number );    #  split input # into chars
    
$_str_len       =   strlen$_number );
    
$_pos           =   0;

    while     (  
$_pos++ < $_str_len )  {
        
$_char          =   $_chars[$_str_len $_pos];
        
$_in_b10       +=   (((int) $_62to10[$_char] ) * $_pwr_of_frB);
        
$_pwr_of_frB   *=   $_frBase;
    }

#   ---- Now convert from base-10 to toBase

    
$_dividend      =   (int)   $_in_b10;         #  name dividend easier to follow below
    
$_in_toB        =   '';                       #  number string in toBase

    
while     ( $_dividend )        {

        
$_quotient  =   (int) ( $_dividend $_toBase );    #  eg. 789 / 62  =  12  ( C in base 62 )
        
$_remainder =   ''  .  ( $_dividend $_toBase );   #  789 % 62  =  45  ( j in base 62 )
        
$_in_toB    =   $_10to62[$_remainder] . $_in_toB;   #  789  (in base 10)  =    Cj  (in base 62)
        
$_dividend  =   $_quotient;                         #  new dividend is the quotient from base division
    
}

    if  ( 
$_in_toB  ==  '' )
          
$_in_toB  =   '0';

    return    
$_in_toB;                           #  base $_toBase string
}
#   --------- examples -------
    
echo base_convert_x'3456789ABCDEF'1610 ) . "\n";    #  920735923817967
    
echo   base_convert'3456789ABCDEF'1610 ) . "\n";    #  920735923817967
?>

[#8] holdoffhunger at gmail dot com [2012-06-24 12:29:37]

The function 'base_convert' looks like it would be perfect for converting a hexadecimal number to a binary number.  That code should look like :

<?php

            
// Author: holdoffhunger@gmail.com

    
$hexadecimal_number "1234567890aBcDeF";
    
$binary_number base_convert($hexadecimal_number162);
    print(
$binary_number);

?>


However, if the hexadecimal number is too large (more than ~40 characters), the result is always a string of zeros as the binary result.  So, I wrote some simple code to specifically handle base conversion with Hexadecimal-to-Binary in PHP :

<?php

            
// Author: holdoffhunger@gmail.com
    
        // Example Hexadecimal
        // ---------------------------------------------

    
$hexadecimal_number "1234567890aBcDeF";

        
// Format Hexadecimal
        // ---------------------------------------------

    
$hexadecimal_to_convert_to_binary_testable strtolower($hexadecimal_number);

        
// Get String Length of Hexadecimal
        // ---------------------------------------------

    
$length_of_text_to_convert_to_binary strlen($hexadecimal_number);

        
// Initialize Result Variable
        // ---------------------------------------------

    
$results_of_hexadecimal_to_binary_conversion "";

        
// Parse Hexadecimal String
        // ---------------------------------------------
    
    
for($i 0$i $length_of_text_to_convert_to_binary$i++)
    {
        
$current_char_of_hexadecimal_for_conversion $hexadecimal_to_convert_to_binary_testable[$i];
        
        switch(
$current_char_of_hexadecimal_for_conversion)
        {
            case 
'0':
                
$results_of_hexadecimal_to_binary_conversion .= "0000";
                break;
                
            case 
'1':
                
$results_of_hexadecimal_to_binary_conversion .= "0001";
                break;
                
            case 
'2':
                
$results_of_hexadecimal_to_binary_conversion .= "0010";
                break;
                
            case 
'3':
                
$results_of_hexadecimal_to_binary_conversion .= "0011";
                break;
                
            case 
'4':
                
$results_of_hexadecimal_to_binary_conversion .= "0100";
                break;
                
            case 
'5':
                
$results_of_hexadecimal_to_binary_conversion .= "0101";
                break;
                
            case 
'6':
                
$results_of_hexadecimal_to_binary_conversion .= "0110";
                break;
                
            case 
'7':
                
$results_of_hexadecimal_to_binary_conversion .= "0111";
                break;
                
            case 
'8':
                
$results_of_hexadecimal_to_binary_conversion .= "1000";
                break;
                
            case 
'9':
                
$results_of_hexadecimal_to_binary_conversion .= "1001";
                break;
                
            case 
'a':
                
$results_of_hexadecimal_to_binary_conversion .= "1010";
                break;
                
            case 
'b':
                
$results_of_hexadecimal_to_binary_conversion .= "1011";
                break;
                
            case 
'c':
                
$results_of_hexadecimal_to_binary_conversion .= "1100";
                break;
                
            case 
'd':
                
$results_of_hexadecimal_to_binary_conversion .= "1101";
                break;
                
            case 
'e':
                
$results_of_hexadecimal_to_binary_conversion .= "1110";
                break;
                
            case 
'f':
                
$results_of_hexadecimal_to_binary_conversion .= "1111";
                break;
        }
    }

        
// Print Results
        // ---------------------------------------------

    
print($results_of_hexadecimal_to_binary_conversion);

        
// Output: (linebreak doesn't appear in results)
    // 00010010001101000101011001111000
    // 10010000101010111100110111101111

?>

[#9] PHPCoder at niconet2k dot com [2011-11-17 10:45:13]

Convert an arbitrarily large number from any base to any base.

string convBase(string $numberInput, string $fromBaseInput, string $toBaseInput)
$numberInput number to convert as a string
$fromBaseInput base of the number to convert as a string
$toBaseInput base the number should be converted to as a string
examples for $fromBaseInput and $toBaseInput
'0123456789ABCDEF' for Hexadecimal (Base16)
'0123456789' for Decimal (Base10)
'01234567' for Octal (Base8)
'01' for Binary (Base2) 
You can really put in whatever you want and the first character is the 0.
Examples:

<?php 
convBase
('123''0123456789''01234567'); 
//Convert '123' from decimal (base10) to octal (base8).
//result: 173

convBase('70B1D707EAC2EDF4C6389F440C7294B51FFF57BB''0123456789ABCDEF''01');
//Convert '70B1D707EAC2EDF4C6389F440C7294B51FFF57BB' from hexadecimal (base16) to binary (base2).
//result: 
//111000010110001110101110000011111101010110000101110
//110111110100110001100011100010011111010001000000110
//001110010100101001011010100011111111111110101011110
//111011

convBase('1324523453243154324542341524315432113200203012''012345''0123456789ABCDEF');
//Convert '1324523453243154324542341524315432113200203012' from senary (base6) to hexadecimal (base16).
//result: 1F9881BAD10454A8C23A838EF00F50

convBase('355927353784509896715106760','0123456789','Christopher');
//Convert '355927353784509896715106760' from decimal (base10) to undecimal (base11) using "Christopher" as the numbers.
//result: iihtspiphoeCrCeshhorsrrtrh

convBase('1C238Ab97132aAC84B72','0123456789aAbBcCdD''~!@#$%^&*()');
//Convert'1C238Ab97132aAC84B72' from octodecimal (base18) using '0123456789aAbBcCdD' as the numbers to undecimal (base11) using '~!@#$%^&*()' as the numbers.
//result: !%~!!*&!~^!!&(&!~^@#@@@&

function convBase($numberInput$fromBaseInput$toBaseInput)
{
    if (
$fromBaseInput==$toBaseInput) return $numberInput;
    
$fromBase str_split($fromBaseInput,1);
    
$toBase str_split($toBaseInput,1);
    
$number str_split($numberInput,1);
    
$fromLen=strlen($fromBaseInput);
    
$toLen=strlen($toBaseInput);
    
$numberLen=strlen($numberInput);
    
$retval='';
    if (
$toBaseInput == '0123456789')
    {
        
$retval=0;
        for (
$i 1;$i <= $numberLen$i++)
            
$retval bcadd($retvalbcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));
        return 
$retval;
    }
    if (
$fromBaseInput != '0123456789')
        
$base10=convBase($numberInput$fromBaseInput'0123456789');
    else
        
$base10 $numberInput;
    if (
$base10<strlen($toBaseInput))
        return 
$toBase[$base10];
    while(
$base10 != '0')
    {
        
$retval $toBase[bcmod($base10,$toLen)].$retval;
        
$base10 bcdiv($base10,$toLen,0);
    }
    return 
$retval;
}
?>

[#10] bpds [2011-09-30 05:47:32]

A simple function to convert an int to any base.

<?php
function intToAlphaBaseN($n,$baseArray) {
    
$l=count($baseArray);
    
$s '';
    for (
$i 1$n >= && $i 10$i++) {
        
$s =  $baseArray[($n pow($l$i) / pow($l$i 1))].$s;
        
$n -= pow($l$i);
    }
    return 
$s;
}

$alpha=array('a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z');
$r=rand(099999999999);
echo(
intToAlphaBaseN($r,$alpha));
?>

[#11] JR [2011-08-16 04:19:57]

Short arabic2roman conveter:

<?php
function rome($N){
        
$c='IVXLCDM';
        for(
$a=5,$b=$s='';$N;$b++,$a^=7)
                for(
$o=$N%$a,$N=$N/$a^0;$o--;$s=$c[$o>2?$b+$N-($N&=-2)+$o=1:$b].$s);
        return 
$s;
}
?>


And it works :)

[#12] bryan at bryanruiz dot com [2011-02-03 03:11:45]

A RFC 4648 Compliant Base32 encode.  Send me an email if you end up making this thing more efficient with bitwise operations and whatever else.

<?php


class Base32 {

   private static $map = array(
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', //  7
        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
        'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
        '='  // padding char
    );
    
   private static $flippedMap = array(
        'A'=>'0', 'B'=>'1', 'C'=>'2', 'D'=>'3', 'E'=>'4', 'F'=>'5', 'G'=>'6', 'H'=>'7',
        'I'=>'8', 'J'=>'9', 'K'=>'10', 'L'=>'11', 'M'=>'12', 'N'=>'13', 'O'=>'14', 'P'=>'15',
        'Q'=>'16', 'R'=>'17', 'S'=>'18', 'T'=>'19', 'U'=>'20', 'V'=>'21', 'W'=>'22', 'X'=>'23',
        'Y'=>'24', 'Z'=>'25', '2'=>'26', '3'=>'27', '4'=>'28', '5'=>'29', '6'=>'30', '7'=>'31'
    );
    
    
    public static function encode($input, $padding = true) {
        if(empty($input)) return "";
        $input = str_split($input);
        $binaryString = "";
        for($i = 0; $i < count($input); $i++) {
         $binaryString .= str_pad(base_convert(ord($input[$i]), 10, 2), 8, '0', STR_PAD_LEFT);
        }
        $fiveBitBinaryArray = str_split($binaryString, 5);
        $base32 = "";
        $i=0;
        while($i < count($fiveBitBinaryArray)) {
         $base32 .= self::$map[base_convert(str_pad($fiveBitBinaryArray[$i], 5,'0'), 2, 10)];
         $i++;
        }
        if($padding && ($x = strlen($binaryString) % 40) != 0) {
         if($x == 8) $base32 .= str_repeat(self::$map[32], 6);
         else if($x == 16) $base32 .= str_repeat(self::$map[32], 4);
         else if($x == 24) $base32 .= str_repeat(self::$map[32], 3);
         else if($x == 32) $base32 .= self::$map[32];
}
return $base32;
    }
    
    public static function decode($input) {
     if(empty($input)) return;
     $paddingCharCount = substr_count($input, self::$map[32]);
     $allowedValues = array(6,4,3,1,0);
     if(!in_array($paddingCharCount, $allowedValues)) return false;
     for($i=0; $i<4; $i++){ 
     if($paddingCharCount == $allowedValues[$i] && 
     substr($input, -($allowedValues[$i])) != str_repeat(self::$map[32], $allowedValues[$i])) return false;
}
     $input = str_replace('=','', $input);
     $input = str_split($input);
     $binaryString = "";
     for($i=0; $i < count($input); $i = $i+8) {
     $x = "";
     if(!in_array($input[$i], self::$map)) return false;
     for($j=0; $j < 8; $j++) {
     $x .= str_pad(base_convert(@self::$flippedMap[@$input[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
}
     $eightBits = str_split($x, 8);
     for($z = 0; $z < count($eightBits); $z++) {
     $binaryString .= ( ($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48 ) ? $y:"";
     }
     }
     return $binaryString;
    }
}

[#13] francesco[at]paladinux.net [2010-09-23 03:30:04]

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);

[#14] Theriault [2009-11-30 02:11:36]

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


function num2alpha($n) {
    
$r '';
    for (
$i 1$n >= && $i 10$i++) {
        
$r chr(0x41 + ($n pow(26$i) / pow(26$i 1))) . $r;
        
$n -= pow(26$i);
    }
    return 
$r;
}

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.

[#15] MFTM [2009-08-16 11:30:31]

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;
}
?>

[#16] cyrilbele at yahoo dot fr [2009-04-16 01:58:18]

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), 1610),4,6);
    return 
$num%$nbShards;
}
?>

[#17] Ray Paseur sometimes uses GMail [2006-12-06 15:55:07]

[EDIT BY danbrown AT php DOT net: This function provides conversion of Arabic numerals (those used by most of the world, the standard 1,2,3,4,...) into Roman numerals (I,II,III,IV,...).  The original author failed to provide a description, but due to the usefulness of the function, it is being preserved from deletion, and a simple description added.]

<?php
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_text31);
    
$anx substr($arabic_numeral_text21);
    
$anc substr($arabic_numeral_text11);
    
$anm substr($arabic_numeral_text01);

    
$roman_numeral_text $roman_numeral_thousands[$anm] . $roman_numeral_hundreds[$anc] . $roman_numeral_tens[$anx] . $roman_numeral_units[$anu];
return (
$roman_numeral_text);
}
?>

[#18] CJ Dennis [2006-04-06 01:03:26]

Really huge numbers might be truncated at both ends.
eg:
<?php
$binary
="11010101001111010001110101000100011110010110110".
"001111000010001010001111001100011010110110010010011010".
"001011010000001001011111110001010101101101011010101010".
"000100011101110010110010100111110001010010111010110011".
"001111111100011001011011001110001111110000101011010010";
print(
strtoupper(base_convert($binary216)));
?>

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.

[#19] lindsay at bitleap dot com [2005-03-18 13:17:24]

If you need to use base_convert with numbers larger then 32 bit, the following gmp implementation of base_convert should work.

<?php


function gmp_convert($num$base_a$base_b)
{
        return 
gmp_strval gmp_init($num$base_a), $base_b );
}

?>

[#20] simon at simonster dot com [2004-06-15 18:05:46]

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_base2);
    
$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$i8), 210)).$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}), 102), 8"0"STR_PAD_LEFT);
    }
    return 
base_convert($number2$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.

[#21] AdamJacobMuller at AdamJacobMuller dot com [2004-04-28 14:20:48]

<?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

[#22] fiftytoo at buckeyeexpress dot com [2003-12-24 00:57:30]

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

?>

[#23] Fips [2003-07-29 11:08:02]

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($numstring01);
            
$pos strpos($baseFrom$char);
            if (
$pos !== FALSE)
            {
                
$decVal += $pos * ($len pow($baseFromLen$len) : 1);
            }
            
$numstring substr($numstring1);
        }
    }
    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($numstring0, ($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)

[#24] tim_converse at yahoo dot com [2000-01-19 15:24:30]

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).

上一篇: 下一篇: