I made a function that can be used for converting numbers to any base you wish.. instead of returning a string of pre-defined index of characters (i.e. 0-9a-z) you could simply make your own of any length using the array of indexes it returns.
I looked around and didn't see anybody made one, I needed one for a simple compression algorithm with only numbers, I've not actually made it yet but this was an initial idea.
<?php
// ConvertBase function explained:
// we add an array item $Input%$Base floored and divide $Input by $Base floored.
// repeat until $Input is no longer above 0.
function ConvertBase($Input,$Base=10) {
$Input=gmp_init($Input);
$Result=array();
for($i=0;$i<1||gmp_sign($Input)==1;$i++) {
$Result[]=gmp_intval(gmp_mod($Input,$Base));
$Input=gmp_div_q($Input,$Base);
}
$Result=array_reverse($Result);
return($Result);
}
// an example how gmp_strval($.., 36); could be achieved:
// the funny emergency number from The IT Crowd
// (leading zeroes aren't liked in gmp_init though)
$Input = '1189998819991197253';
// our example 36 characters used in gmp_strval($.., 36);
$Chars = '0123456789abcdefghijklmnopqrstuvwxyz';
// count the $Chars so they're all used
// or use your own number less than the length of $Chars
$Base = strlen($Chars);
// perform
$Result = ConvertBase($Input,$Base);
// replace the resulting index with the corrosponding characters of the index in $Chars
for($i=0;$i<count($Result);$i++)
$Result[$i]=$Chars{$Result[$i]};
// compare
printf("gmp_strval: %s\r\n",gmp_strval($Input,36));
printf("BaseConvert: %s\r\n",implode($Result));
/* OUTPUT:
gmp_strval: 91h7dixfq6h1
BaseConvert: 91h7dixfq6h1
*/
?>
The example shows a familiar result of course, but the idea of this function was so that you can use whatever base you wish, and display entirely your own output to represent any number of choice.
Also, for those who wish to do bitwise shifting, it's quite simple.. to shift left, just multiply the number by pow(2,x), and to shift right, divide by pow(2,x).
<?php
function gmp_shiftl($x,$n) { // shift left
return(gmp_mul($x,gmp_pow(2,$n)));
}
function gmp_shiftr($x,$n) { // shift right
return(gmp_div($x,gmp_pow(2,$n)));
}
?>
Have fun,
Nitrogen.
L. Fonctions GMP
Introduction
Ces fonctions vous permettent de travailler avec des nombres de taille arbitraire, en utilisant la bibliothèque GNU MP.
Ces fonctions ont été ajoutées en PHP 4.0.4.
Note : La majorité des fonctions GMP acceptent des nombres GMP comme arguments, définis ci-dessous comme resource. Cependant, la plupart de ces fonctions acceptent aussi des nombres et des chaînes à partir du moment où on peut les convertir en nombre. Si une fonction utilisant les entiers est plus rapide, elle sera automatiquement appelée si les arguments fournis sont des entiers. Cela se fait de manière transparente : vous pouvez donc utiliser des entiers avec les fonctions GMP sans perte de vitesse. Voir aussi gmp_init().
| Avertissement |
Si vous voulez explicitement spécifier un entier de grande taille, spécifiez-le sous forme de chaîne. Si vous ne le faites pas, PHP va interpréter votre entier et le transformer en une représentation interne, qui vous fera sûrement perdre de la précision, avant même que GMP n'entre en jeu. |
Note : Cette extension est disponible sur les plates-formes Windows depuis PHP 5.1.0.
Pré-requis
Vous pouvez télécharger GMP sur le site de http://www.swox.com/gmp/. Ce site propose aussi un manuel GMP.
Vous devez utiliser GMP 2 ou plus récent pour utiliser ces fonctions. Certaines d'entre elles peuvent requérir une version encore plus récente de GMP.
Installation
Pour pouvoir utiliser ces fonctions, vous devez compiler PHP GMP en utilisant l'option --with-gmp.
Configuration à l'exécution
Cette extension ne définit aucune directive de configuration.
Types de ressources
Cette extension ne définit aucune ressource.
Constantes pré-définies
Ces constantes sont définies par cette extension, et ne sont disponibles que si cette extension a été compilée avec PHP, ou bien chargée au moment de l'exécution.
Voir aussi
D'autres fonctions mathématiques sont disponibles avec les extensions Nombres de grande taille BCMath et Mathématiques.
- Table des matières
- gmp_abs -- Valeur absolue GMP
- gmp_add -- Addition de 2 nombres GMP
- gmp_and -- ET logique
- gmp_clrbit -- Annule un bit
- gmp_cmp -- Compare des nombres GMP
- gmp_com -- Calcule le complémentaire d'un nombre
- gmp_div_q -- Divisions de 2 nombres GMP
- gmp_div_qr -- Divise deux nombres GMP
- gmp_div_r -- Reste de la division de deux nombres GMP
- gmp_div -- Alias de gmp_div_q()
- gmp_divexact -- Division exacte de nombres GMP
- gmp_fact -- Factorielle GMP
- gmp_gcd -- PGCD
- gmp_gcdext -- PGCD étendu
- gmp_hamdist -- Distance de Hamming
- gmp_init -- Crée un nombre GMP
- gmp_intval -- Convertit un nombre GMP en entier
- gmp_invert -- Inverse modulo
- gmp_jacobi -- Symbole de Jacobi
- gmp_legendre -- Symbole de Legendre
- gmp_mod -- Modulo GMP
- gmp_mul -- Multiplication de 2 nombres GMP
- gmp_neg -- Opposé de nombre GMP
- gmp_nextprime -- Trouve le prochain nombre premier
- gmp_or -- OU logique
- gmp_perfect_square -- Carré parfait GMP
- gmp_popcount -- Compte de population
- gmp_pow -- Puissance
- gmp_powm -- Puissance et modulo
- gmp_prob_prime -- Nombre GMP probablement premier
- gmp_random -- Nombre GMP aléatoire
- gmp_scan0 -- Recherche 0
- gmp_scan1 -- Recherche 1
- gmp_setbit -- Modifie un bit
- gmp_sign -- Signe du nombre GMP
- gmp_sqrt -- Racine carrée GMP
- gmp_sqrtrem -- Racine carrée avec reste GMP
- gmp_strval -- Convertit un nombre GMP en chaîne
- gmp_sub -- Soustraction de 2 nombres GMP
- gmp_xor -- OU exclusif logique
Here's a quick and dirty way to use simple GMP functions with PHP without recompiling. It is dependent upon the use of the exec() function, so make sure you can use exec(). While in safe mode you must consider the safe_mode_exec_dir directive. And don't simply pass user input to the exec function without validating the input first!
Download and Install GMP as instructed in README and INSTALL files.
On my MAC OS X Server, I just did the following:
./configure
make
make check
make install
This installed it in the /usr/local directory. There were some errors, but not with any functions I needed.
Within the gmp-4.#.# cd into the demos directory. Then compile pexpr.c by typing:
make pexpr
This is a simple expressions parser which serves as a simple interface to some of the basic GMP functions.
You can test it then like:
./pexpr "102394874783 * 23498748";
Now you may interface with it using PHP's exec() function.
For those (like me) who are trying to do bit masking with very large numbers, here is a useful function to do the work for you.
<?php
function isBitSet($bitMask, $bitMap)
{
return (bool) gmp_intval(gmp_div(gmp_and($bitMask, $bitMap),$bitMask));
}
?>
=============================================================
A set of very nice functions to handle IP Address with gmplib:
The best way to store a range into a database is store:
dNet ..... decimal representation of a Net
dMask .... decimal representation of a Mask
All another parameters can be calculated.
<?
/*
f_ip2dec($a) ................... IP string to decimal
f_dec2ip($a) ................... decimal to IP string
f_dec2ipall($dNet,$dMask) ...... decimal Net and Mask to an Array with several IP parameters
f_dec2cidr($a) ................. decimal Mask to CIDR
f_and($a,$b) ................... and
f_or($a,$b) .................... or
f_xor($a,$b) ................... xor
f_not($a) ...................... not
f_dec2bin($a) .................. decimal to binary string
f_bin2dec($a) .................. binary string to decimal
*/
function f_and($a,$b){
$a=gmp_init(strval($a));
$b=gmp_init(strval($b));
$d=gmp_and($a,$b);
return floatval(gmp_strval($d));
}
function f_or($a,$b){
$a=gmp_init(strval($a));
$b=gmp_init(strval($b));
$d=gmp_or($a,$b);
return floatval(gmp_strval($d));
}
function f_xor($a,$b){
$a=gmp_init(strval($a));
$b=gmp_init(strval($b));
$d=gmp_xor($a,$b);
return floatval(gmp_strval($d));
}
function f_not($a){
$a=gmp_init(strval($a));
$d=gmp_strval($a,2);
$d=str_replace("1","x",$d);
$d=str_replace("0","1",$d);
$d=str_replace("x","0",$d);
$d=gmp_init($d,2);
return floatval(gmp_strval($d,10));
}
function f_dec2bin($a){
$a=gmp_init(strval($a));
return gmp_strval($a,2);
}
function f_bin2dec($a){
$a=gmp_init(strval($a),2);
return floatval(gmp_strval($a,10));
}
function f_ip2dec($a){
$d = 0.0;
$b = explode(".", $a,4);
for ($i = 0; $i < 4; $i++) {
$d *= 256.0;
$d += $b[$i];
};
return $d;
}
function f_dec2ip($a){
$b=array(0,0,0,0);
$c = 16777216.0;
$a += 0.0;
for ($i = 0; $i < 4; $i++) {
$k = (int) ($a / $c);
$a -= $c * $k;
$b[$i]= $k;
$c /=256.0;
};
$d=join('.', $b);
return($d);
}
function f_dec2cidr($a){
$a=gmp_init(strval($a));
$d=strlen(str_replace("0","",gmp_strval($a,2)));
return $d;
}
function f_dec2ipall($dNet,$dMask){
$dWildCard=f_not($dMask);
$IpAll["Net"]=f_dec2ip($dNet);
$IpAll["Mask"]=f_dec2ip($dMask);
$IpAll["WildCard"]=f_dec2ip($dWildCard);
$IpAll["Cidr"]=f_dec2cidr($dMask);
$IpAll["Bcast"]=f_dec2ip(f_or($dNet,$dWildCard));
$IpAll["nIp"]=$dWildCard+1;
$IpAll["nIpUtil"]=$dWildCard-1;
if($IpAll["nIp"] > 2){
$IpAll["IpFrom"]=f_dec2ip($dNet+1);
$IpAll["IpTo"]=f_dec2ip($dNet+$dWildCard-1);
}
else
{
$IpAll["IpFrom"]="-";
$IpAll["IpTo"]="-";
$IpAll["nIpUtil"]=0;
}
return $IpAll;
}
?>
=============================================================
GMP install steps in Mandrake 9.1:
----------------------------------------------------------
cp -r /usr/src/php-devel/extensions/gmp /tmp/gmp
cd /tmp/gmp
phpize
./configure
make install
echo "extension = gmp.so" > /etc/php/90_gmp.ini
Restart apache web server.
----------------------------------------------------------
gmp.so is in:
/usr/lib/php/extensions/
look in phpinfo, the string:
/etc/php/90_gmp.ini
Needs these tools:
autoconf
automake
libtool
m4
php430-devel-430-11mdk.rpm
all rpm´s that are envolved to run and compile gmp (*gmp*.rpm)
Some docs about self contained extensions:
/usr/share/doc/php430-devel-430/SELF-CONTAINED-EXTENSIONS
=============================================================
