Math_Basex
[ class tree: Math_Basex ] [ index: Math_Basex ] [ all elements ]

Source for file Basex.php

Documentation is available at Basex.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Dave Mertens <dmertens@zyprexia.com>                        |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: Basex.php 288478 2009-09-20 17:23:02Z saltybeagle $
  20.  
  21. require_once "PEAR.php";
  22.  
  23. if (!defined('MATH_BASEX_MATHEXTENSION')) {
  24.     if (PEAR::loadExtension('bcmath')) {
  25.         define('MATH_BASEX_MATHEXTENSION''bcmath');
  26.     elseif (PEAR::loadExtension('gmp')) {
  27.         define('MATH_BASEX_MATHEXTENSION''gmp');
  28.     else {
  29.         define('MATH_BASEX_MATHEXTENSION''none');
  30.     }
  31. }
  32.  
  33. /**
  34. * base X coding class
  35. *
  36. * I noticed that value of an int is different on most systems.
  37. * On my system (linux 2.4.18 with glibc 2.2.5) i can use 8-byte integers
  38. * (also called int64 or int8)
  39. * On my laptop (Windows 2000) i only could use numbers up to 4-byte (32 bit)
  40. * integers.
  41. * So you might want to test this first!
  42. *
  43. * Note that you can without much effort also use the bcmath extentions to
  44. * increase the length of your numbers.
  45. *
  46. @category Math
  47. @package  Math_Basex
  48. @author   Dave Mertens <dmertens@zyprexia.com>
  49. @version  0.3.1
  50. @access   public
  51. @link     http://pear.php.net/package/Math_Basex
  52. */
  53. class Math_Basex
  54. {
  55.     /**
  56.     * @var character base set
  57.     * @access private;
  58.     */
  59.     var $_baseChars;
  60.  
  61.     /**
  62.     * @var base length (for binair 2, dec 10, hex 16, yours ??)
  63.     * @access private;
  64.     */
  65.     var $_length;
  66.     
  67.     /**
  68.     * Constructor for class
  69.     *
  70.     * @param string $tokens Character base set (Each character is only allowed
  71.     *                                           once!)
  72.     *
  73.     * @return void 
  74.     */
  75.     function Math_Basex($tokens "")
  76.     {
  77.         //set initial length
  78.         $this->_length = 0;
  79.         
  80.         //if we did get already a character set, set it..
  81.         if (!empty($tokens)) {
  82.             $this->setBase($tokens);
  83.         }
  84.     }
  85.             
  86.     
  87.     /**
  88.     * Change the character base set. Behaves the same way the constructor does.
  89.     *
  90.     * @param string $tokens Character base set (Each character is only allowed
  91.     *                                           once!)
  92.     *
  93.     * @return void 
  94.     * @access public
  95.     */
  96.     function setBase($tokens)
  97.     {
  98.         if (!$this->_checkBase($tokens)) {
  99.             return PEAR::raiseError("Each character is only allowed once");
  100.         }
  101.         $this->_baseChars $tokens;
  102.         $this->_length strlen($tokens);
  103.         return true;
  104.     }
  105.     
  106.     /**
  107.     * toBase translates a decimal (base 10) number into your base 'code'
  108.     *
  109.     * @param mixed $number (int64 or double without floats, both are 8-byte number
  110.     *          types). This allows you to use numbers up to 18446744073709551616.
  111.     *
  112.     * @return string encoded 'code' of yout decimal number
  113.     */
  114.     function toBase($number)
  115.     {
  116.         if (!is_numeric($number)) {
  117.             return PEAR::raiseError("You must supply a decimal number");
  118.         }
  119.             
  120.         if ($this->_length == 0{
  121.             return PEAR::raiseError("Character base isn't defined yet..");
  122.         }
  123.         if (is_float($number)) {
  124.             $number ltrim(sprintf('%22.0f'$number));
  125.         }
  126.  
  127.         $code "";
  128.         do {
  129.             $this->_splitnumber($number$full$mod);
  130.             $code $this->_getToken($mod$code;
  131.             $number $full;
  132.         while ($number > 0);
  133.         
  134.         return $code;
  135.         
  136.     }
  137.     
  138.     /**
  139.     * toDecimal decodes the baseX 'code' back to a decimal number
  140.     *
  141.     * @param string $code code to decode
  142.     * 
  143.     * @return int64 decimal (base 10) number
  144.     */
  145.     function todecimal($code)
  146.     {
  147.         $length strlen($code);
  148.         $total = 0;
  149.         
  150.         if (strspn($code$this->_baseChars!= $length{
  151.             return PEAR::raiseError("Your Base X code contains invalid"
  152.                                    ." characters");
  153.         }
  154.  
  155.         for ($i=0; $i $length$i++{
  156.             $sum $this->_getNumber($code[$length $i - 1]
  157.                                      $this->_pow($this->_length$i);
  158.             $total $this->_add($total$sum);
  159.         }
  160.         
  161.         return $total;
  162.     }
  163.     
  164.     /**
  165.     * Returns the base scale. Note that this is onyl the count of the
  166.     * characters used for the encoding and decoding.
  167.     * Please do not use base_convert with this class, because it might result
  168.     * in rare results
  169.     *
  170.     * @access public
  171.     * @return integer 
  172.     */
  173.     function getBase()
  174.     {
  175.         return $this->_length;
  176.     }
  177.     
  178.     /**
  179.     * Validates whether each character is unique
  180.     *
  181.     * @param string $tokens Character base set
  182.     * 
  183.     * @access private
  184.     * @return boolean true if all characters are unique
  185.     */
  186.     function _checkBase($tokens)
  187.     {
  188.         $length strlen($tokens);
  189.         for ($i=0; $i $length$i++{
  190.             if (substr_count($tokens$tokens[$i]> 1)
  191.                 return false;    //character is specified more than one time!
  192.         }
  193.         
  194.         //if we come here, all characters are unique
  195.         return true;
  196.     }
  197.     
  198.     /**
  199.     * Helper function for encoding function.
  200.     *
  201.     * @param int   $number   number to spilt for base conversion
  202.     * @param int   &$full    non-float, unrounded number (will be passed as
  203.     *                         reference)
  204.     * @param float &$modules floating number between 0 and 1
  205.     *                         (will be passed as reference)
  206.     *
  207.     * @access private
  208.     * @return void 
  209.     */
  210.     function _splitNumber($number&$full&$modules)
  211.     {
  212.         $full $this->_div($number$this->_length);
  213.         $modules $this->_mod($number$this->_length);
  214.     }
  215.  
  216.     /**
  217.     * Helper function; Returns character at position x
  218.     *
  219.     * @param int $oneDigit number between 0 and basex->getBase()
  220.     * 
  221.     * @return character from base character set
  222.     * @access private;
  223.     */
  224.     function _getToken($oneDigit)
  225.     {
  226.         return substr($this->_baseChars$oneDigit1);
  227.     }
  228.     
  229.     /**
  230.     * Helper function; Returns position of character X
  231.     *
  232.     * @param string $oneDigit Character in base character set
  233.     * 
  234.     * @return int number between 0 and basex->getBase()
  235.     * @access private;
  236.     */
  237.     function _getNumber($oneDigit)
  238.     {
  239.         return strpos($this->_baseChars$oneDigit);
  240.     }    
  241.  
  242.     /**
  243.     * Add two numbers, utilize Math extensions
  244.     *
  245.     * @param mixed $a First operand
  246.     * @param mixed $b Second operand
  247.     * 
  248.     * @return mixed 
  249.     * @access private
  250.     */
  251.     function _add($a$b)
  252.     {
  253.         switch (MATH_BASEX_MATHEXTENSION{
  254.         case 'bcmath':
  255.             return bcadd($a$b);
  256.         case 'gmp':
  257.             return gmp_strval(gmp_add($a$b));
  258.         case 'none':
  259.             return $a $b;
  260.         }
  261.     }
  262.  
  263.     /**
  264.     * Multiply two numbers, utilize Math extensions
  265.     *
  266.     * @param mixed $a First operand
  267.     * @param mixed $b Second operand
  268.     * 
  269.     * @return mixed 
  270.     * @access private
  271.     */
  272.     function _mul($a$b)
  273.     {
  274.         switch (MATH_BASEX_MATHEXTENSION{
  275.         case 'bcmath':
  276.             return bcmul($a$b);
  277.         case 'gmp':
  278.             return gmp_strval(gmp_mul($a$b));
  279.         case 'none':
  280.             return $a $b;
  281.         }
  282.  
  283.     }
  284.  
  285.     /**
  286.     * Return the modulo of two numbers, utilize Math extensions
  287.     *
  288.     * @param mixed $a First operand
  289.     * @param mixed $b Second operand
  290.     * 
  291.     * @return mixed 
  292.     * @access private
  293.     */
  294.     function _mod($a$b)
  295.     {
  296.         switch (MATH_BASEX_MATHEXTENSION{
  297.         case 'bcmath':
  298.             return bcmod($a$b);
  299.         case 'gmp':
  300.             return gmp_strval(gmp_mod($a$b));
  301.         case 'none':
  302.             return $a $b;
  303.         }
  304.     }
  305.  
  306.     /**
  307.     * Divide two integers, utilize Math extensions
  308.     *
  309.     * @param mixed $a First operand
  310.     * @param mixed $b Second operand
  311.     * 
  312.     * @return mixed 
  313.     * @access private
  314.     */
  315.     function _div($a$b)
  316.     {
  317.         switch (MATH_BASEX_MATHEXTENSION{
  318.         case 'bcmath':
  319.             return bcdiv($a$b);
  320.         case 'gmp':
  321.             return gmp_strval(gmp_div($a$b));
  322.         case 'none':
  323.             return floor($a $b);
  324.         }
  325.     }
  326.  
  327.     /**
  328.     * Raise one number to the power of the other, utilize Math extensions
  329.     *
  330.     * @param mixed $a First operand
  331.     * @param mixed $b Second operand
  332.     * 
  333.     * @return mixed 
  334.     * @access private
  335.     */
  336.     function _pow($a$b)
  337.     {
  338.         switch (MATH_BASEX_MATHEXTENSION{
  339.         case 'bcmath':
  340.             return bcpow($a$b);
  341.         case 'gmp':
  342.             return gmp_strval(gmp_pow($a$b));
  343.         case 'none':
  344.             return pow($a$b);
  345.         }
  346.     }
  347.  
  348.     /**
  349.     * Returns a common set of digits (0-9A-Za-z), length is given as parameter
  350.     *
  351.     * @param int $n Optional How many characters to return, defaults to 62.
  352.     * 
  353.     * @return string 
  354.     * @access public
  355.     */
  356.     function stdBase($n = 62
  357.     {
  358.         return substr("0123456789"
  359.                      ."ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  360.                      ."abcdefghijklmnopqrstuvwxyz"0$n);
  361.     }
  362.  
  363.     /**
  364.     * Converts a number from one base into another. May be called statically.
  365.     * 
  366.     * @param mixed  $number    The number to convert
  367.     * @param int    $from_base The base to convert from
  368.     * @param int    $to_base   The base to convert to
  369.     * @param string $from_cs   Optional character set of the number that is
  370.     *                                 converted
  371.     * @param string $to_cs     Optional character set of the target number
  372.     * 
  373.     * @return string 
  374.     * @access public
  375.     */
  376.     function baseConvert($number$from_base$to_base
  377.                           $from_cs = null$to_cs = null)
  378.     {
  379.         if (isset($this)) {
  380.             $obj &$this;
  381.         else {
  382.             $obj &Math_Basex::instance();
  383.         }
  384.         if (!isset($from_cs)) {
  385.             $from_cs $obj->stdBase();
  386.         }
  387.         if (!isset($to_cs)) {
  388.             $to_cs $obj->stdBase();
  389.         }
  390.         if (strlen($from_cs$from_base{
  391.             return PEAR::raiseError('Character set isn\'t long enough for the'
  392.                                    .'given base.');
  393.         }
  394.         if (strlen($to_cs$to_base{
  395.             return PEAR::raiseError('Character set isn\'t long enough for the'
  396.                                    .'given base.');
  397.         }
  398.         $from_cs substr($from_cs0$from_base);
  399.         $to_cs   substr($to_cs0$to_base);
  400.         if ($tmp $obj->setBase($from_cs!== true{
  401.             return $tmp;
  402.         }
  403.         $number $obj->toDecimal($number);
  404.         if (PEAR::isError($number)) {
  405.             return $number;
  406.         }
  407.         if ($tmp $obj->setBase($to_cs!== true{
  408.             return $tmp;
  409.         }
  410.         $number $obj->toBase($number);
  411.         return $number;
  412.     }
  413.  
  414.     /**
  415.     * Singleton method, call statically
  416.     *
  417.     * @return object 
  418.     * @access public
  419.     */
  420.     function &instance()
  421.     {
  422.         static $ins = null;
  423.         if (is_null($ins)) {
  424.             $ins = new Math_Basex;
  425.         }
  426.         return $ins;
  427.     }
  428. }
  429.  
  430. ?>

Documentation generated on Mon, 11 Mar 2019 15:34:42 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.