$b * - zero if $a == $b * - a negative value if $a < $b * * @param mixed $a The first number * @param mixed $b The second number * @return int */ abstract public function cmp( $a, $b ); /** * Returns the string representation of number $a. * * @param mixed $a The number to be represented as a string * @return string */ abstract public function toString( $a ); /** * Converts a binary value to a decimal value. * * @param mixed $bin Binary value * @return string */ public function binToDec( $bin ) { $dec = $this->init( 0 ); while ( strlen( $bin ) ) { $i = ord( substr( $bin, 0, 1 ) ); $dec = $this->add( $this->mul( $dec, 256 ), $i ); $bin = substr( $bin, 1 ); } return $this->toString( $dec ); } /** * Converts an hexadecimal value to a decimal value. * * @param mixed $hex Hexadecimal value * @return string */ public function hexToDec( $hex ) { $dec = $this->init( 0 ); while ( strlen( $hex ) ) { $i = hexdec( substr( $hex, 0, 4 ) ); $dec = $this->add( $this->mul( $dec, 65536 ), $i ); $hex = substr( $hex, 4 ); } return $this->toString( $dec ); } /** * Returns bignum $number in big-endian signed two's complement. * * @param mixed $number The number to convert * @return mixed */ public function btwoc( $number ) { $cmp = $this->cmp( $number, 0 ); if ( $cmp < 0 ) { return null; } elseif ( $cmp === 0 ) { return "\x00"; } $bytes = array(); while ( $this->cmp( $number, 0 ) > 0 ) { array_unshift( $bytes, $this->mod( $number, 256 ) ); $number = $this->div( $number, 256 ); } if ( $bytes && ( $bytes[0] > 127 ) ) { array_unshift( $bytes, 0 ); } $string = ''; foreach ( $bytes as $byte ) { $string .= pack( 'C', $byte ); } return $string; } /** * Generates a random bignum. * * @param mixed $stop The top limit of the random number * @return mixed */ public function rand( $stop ) { $num_bytes = strlen( $this->btwoc( $stop ) ); $bytes = ''; for ( $i = 0; $i < $num_bytes; $i += 4 ) { $bytes .= pack( 'L', mt_rand() ); } $bytes = "\x00" . substr( $bytes, 0, $num_bytes ); $n = $this->binToDec( $bytes ); return $this->mod( $n, $stop ); } } ?>