⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bigmath.php

📁 简介:IceBB是一个强大
💻 PHP
字号:
<?php/** * BigMath: A math library wrapper that abstracts out the underlying * long integer library. * * PHP versions 4 and 5 * * LICENSE: See the COPYING file included in this distribution. * * @access private * @package OpenID * @author JanRain, Inc. <openid@janrain.com> * @copyright 2005 Janrain, Inc. * @license http://www.gnu.org/copyleft/lesser.html LGPL *//** * Needed for random number generation */require_once 'Auth/OpenID/CryptUtil.php';/** * Need Auth_OpenID::bytes(). */require_once 'Auth/OpenID.php';/** * The superclass of all big-integer math implementations * @access private * @package OpenID */class Auth_OpenID_MathLibrary {    /**     * Given a long integer, returns the number converted to a binary     * string.  This function accepts long integer values of arbitrary     * magnitude and uses the local large-number math library when     * available.     *     * @param integer $long The long number (can be a normal PHP     * integer or a number created by one of the available long number     * libraries)     * @return string $binary The binary version of $long     */    function longToBinary($long)    {        $cmp = $this->cmp($long, 0);        if ($cmp < 0) {            $msg = __FUNCTION__ . " takes only positive integers.";            trigger_error($msg, E_USER_ERROR);            return null;        }        if ($cmp == 0) {            return "\x00";        }        $bytes = array();        while ($this->cmp($long, 0) > 0) {            array_unshift($bytes, $this->mod($long, 256));            $long = $this->div($long, pow(2, 8));        }        if ($bytes && ($bytes[0] > 127)) {            array_unshift($bytes, 0);        }        $string = '';        foreach ($bytes as $byte) {            $string .= pack('C', $byte);        }        return $string;    }    /**     * Given a binary string, returns the binary string converted to a     * long number.     *     * @param string $binary The binary version of a long number,     * probably as a result of calling longToBinary     * @return integer $long The long number equivalent of the binary     * string $str     */    function binaryToLong($str)    {        if ($str === null) {            return null;        }        // Use array_merge to return a zero-indexed array instead of a        // one-indexed array.        $bytes = array_merge(unpack('C*', $str));        $n = $this->init(0);        if ($bytes && ($bytes[0] > 127)) {            trigger_error("bytesToNum works only for positive integers.",                          E_USER_WARNING);            return null;        }        foreach ($bytes as $byte) {            $n = $this->mul($n, pow(2, 8));            $n = $this->add($n, $byte);        }        return $n;    }    function base64ToLong($str)    {        $b64 = base64_decode($str);        if ($b64 === false) {            return false;        }        return $this->binaryToLong($b64);    }    function longToBase64($str)    {        return base64_encode($this->longToBinary($str));    }    /**     * Returns a random number in the specified range.  This function     * accepts $start, $stop, and $step values of arbitrary magnitude     * and will utilize the local large-number math library when     * available.     *     * @param integer $start The start of the range, or the minimum     * random number to return     * @param integer $stop The end of the range, or the maximum     * random number to return     * @param integer $step The step size, such that $result - ($step     * * N) = $start for some N     * @return integer $result The resulting randomly-generated number     */    function rand($stop)    {        static $duplicate_cache = array();        // Used as the key for the duplicate cache        $rbytes = $this->longToBinary($stop);        if (array_key_exists($rbytes, $duplicate_cache)) {            list($duplicate, $nbytes) = $duplicate_cache[$rbytes];        } else {            if ($rbytes[0] == "\x00") {                $nbytes = Auth_OpenID::bytes($rbytes) - 1;            } else {                $nbytes = Auth_OpenID::bytes($rbytes);            }            $mxrand = $this->pow(256, $nbytes);            // If we get a number less than this, then it is in the            // duplicated range.            $duplicate = $this->mod($mxrand, $stop);            if (count($duplicate_cache) > 10) {                $duplicate_cache = array();            }            $duplicate_cache[$rbytes] = array($duplicate, $nbytes);        }        do {            $bytes = "\x00" . Auth_OpenID_CryptUtil::getBytes($nbytes);            $n = $this->binaryToLong($bytes);            // Keep looping if this value is in the low duplicated range        } while ($this->cmp($n, $duplicate) < 0);        return $this->mod($n, $stop);    }}/** * Exposes BCmath math library functionality. * * {@link Auth_OpenID_BcMathWrapper} wraps the functionality provided * by the BCMath extension. * * @access private * @package OpenID */class Auth_OpenID_BcMathWrapper extends Auth_OpenID_MathLibrary{    var $type = 'bcmath';    function add($x, $y)    {        return bcadd($x, $y);    }    function sub($x, $y)    {        return bcsub($x, $y);    }    function pow($base, $exponent)    {        return bcpow($base, $exponent);    }    function cmp($x, $y)    {        return bccomp($x, $y);    }    function init($number, $base = 10)    {        return $number;    }    function mod($base, $modulus)    {        return bcmod($base, $modulus);    }    function mul($x, $y)    {        return bcmul($x, $y);    }    function div($x, $y)    {        return bcdiv($x, $y);    }    /**     * Same as bcpowmod when bcpowmod is missing     *     * @access private     */    function _powmod($base, $exponent, $modulus)    {        $square = $this->mod($base, $modulus);        $result = 1;        while($this->cmp($exponent, 0) > 0) {            if ($this->mod($exponent, 2)) {                $result = $this->mod($this->mul($result, $square), $modulus);            }            $square = $this->mod($this->mul($square, $square), $modulus);            $exponent = $this->div($exponent, 2);        }        return $result;    }    function powmod($base, $exponent, $modulus)    {        if (function_exists('bcpowmod')) {            return bcpowmod($base, $exponent, $modulus);        } else {            return $this->_powmod($base, $exponent, $modulus);        }    }    function toString($num)    {        return $num;    }}/** * Exposes GMP math library functionality. * * {@link Auth_OpenID_GmpMathWrapper} wraps the functionality provided * by the GMP extension. * * @access private * @package OpenID */class Auth_OpenID_GmpMathWrapper extends Auth_OpenID_MathLibrary{    var $type = 'gmp';    function add($x, $y)    {        return gmp_add($x, $y);    }    function sub($x, $y)    {        return gmp_sub($x, $y);    }    function pow($base, $exponent)    {        return gmp_pow($base, $exponent);    }    function cmp($x, $y)    {        return gmp_cmp($x, $y);    }    function init($number, $base = 10)    {        return gmp_init($number, $base);    }    function mod($base, $modulus)    {        return gmp_mod($base, $modulus);    }    function mul($x, $y)    {        return gmp_mul($x, $y);    }    function div($x, $y)    {        return gmp_div_q($x, $y);    }    function powmod($base, $exponent, $modulus)    {        return gmp_powm($base, $exponent, $modulus);    }    function toString($num)    {        return gmp_strval($num);    }}/** * Define the supported extensions.  An extension array has keys * 'modules', 'extension', and 'class'.  'modules' is an array of PHP * module names which the loading code will attempt to load.  These * values will be suffixed with a library file extension (e.g. ".so"). * 'extension' is the name of a PHP extension which will be tested * before 'modules' are loaded.  'class' is the string name of a * {@link Auth_OpenID_MathWrapper} subclass which should be * instantiated if a given extension is present. * * You can define new math library implementations and add them to * this array. */function Auth_OpenID_math_extensions(){    $result = array();    if (!defined('Auth_OpenID_BUGGY_GMP')) {        $result[] =            array('modules' => array('gmp', 'php_gmp'),                  'extension' => 'gmp',                  'class' => 'Auth_OpenID_GmpMathWrapper');    }    $result[] = array(                      'modules' => array('bcmath', 'php_bcmath'),                      'extension' => 'bcmath',                      'class' => 'Auth_OpenID_BcMathWrapper');    return $result;}/** * Detect which (if any) math library is available */function Auth_OpenID_detectMathLibrary($exts){    $loaded = false;    foreach ($exts as $extension) {        // See if the extension specified is already loaded.        if ($extension['extension'] &&            extension_loaded($extension['extension'])) {            $loaded = true;        }        // Try to load dynamic modules.        if (!$loaded) {            foreach ($extension['modules'] as $module) {                if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {                    $loaded = true;                    break;                }            }        }        // If the load succeeded, supply an instance of        // Auth_OpenID_MathWrapper which wraps the specified        // module's functionality.        if ($loaded) {            return $extension;        }    }    return false;}/** * {@link Auth_OpenID_getMathLib} checks for the presence of long * number extension modules and returns an instance of * {@link Auth_OpenID_MathWrapper} which exposes the module's * functionality. * * Checks for the existence of an extension module described by the * result of {@link Auth_OpenID_math_extensions()} and returns an * instance of a wrapper for that extension module.  If no extension * module is found, an instance of {@link Auth_OpenID_MathWrapper} is * returned, which wraps the native PHP integer implementation.  The * proper calling convention for this method is $lib =& * Auth_OpenID_getMathLib(). * * This function checks for the existence of specific long number * implementations in the following order: GMP followed by BCmath. * * @return Auth_OpenID_MathWrapper $instance An instance of * {@link Auth_OpenID_MathWrapper} or one of its subclasses * * @package OpenID */function &Auth_OpenID_getMathLib(){    // The instance of Auth_OpenID_MathWrapper that we choose to    // supply will be stored here, so that subseqent calls to this    // method will return a reference to the same object.    static $lib = null;    if (isset($lib)) {        return $lib;    }    if (Auth_OpenID_noMathSupport()) {        $null = null;        return $null;    }    // If this method has not been called before, look at    // Auth_OpenID_math_extensions and try to find an extension that    // works.    $ext = Auth_OpenID_detectMathLibrary(Auth_OpenID_math_extensions());    if ($ext === false) {        $tried = array();        foreach (Auth_OpenID_math_extensions() as $extinfo) {            $tried[] = $extinfo['extension'];        }        $triedstr = implode(", ", $tried);        Auth_OpenID_setNoMathSupport();        $result = null;        return $result;    }    // Instantiate a new wrapper    $class = $ext['class'];    $lib = new $class();    return $lib;}function Auth_OpenID_setNoMathSupport(){    if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) {        define('Auth_OpenID_NO_MATH_SUPPORT', true);    }}function Auth_OpenID_noMathSupport(){    return defined('Auth_OpenID_NO_MATH_SUPPORT');}?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -