Source for file BinaryUtils.php
Documentation is available at BinaryUtils.php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Markus Nix <mnix@docuverse.de> |
// +----------------------------------------------------------------------+
define('MATH_BINARYUTILS_BIG_ENDIAN', 0x0000 );
define('MATH_BINARYUTILS_LITTLE_ENDIAN', 0x0001 );
* Class with static helpers for easy handling of bit and byte stuff.
* @author Markus Nix <mnix@docuverse.de>
* @version $Id: BinaryUtils.php,v 1.2 2004/09/08 11:56:11 docuverse_de Exp $
function add($num1, $num2)
// compute two's compliment
* @param string $binstring
for ($i = 0; $i < strlen($binstring); $i++ ) {
$decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1 , 1 )) * pow(2 , $i);
while ( $number >= 256 ) {
$bytes[] = (($number / 256 ) - (floor($number / 256 ))) * 256;
$number = floor($number / 256 );
for ($i = 0; $i < count( $bytes ); $i++ ) {
$binstring = (($i == count($bytes) - 1 )? decbin($bytes[" $i" ]) : str_pad(decbin($bytes[" $i" ]), 8 , '0', STR_PAD_LEFT )) . $binstring;
* Converts a single-precision floating point number
* to a 6 byte binary string.
* @param float $num the float to convert
* @return string the binary string representing the float
$sign = ($num < 0 )? 0x8000 : 0x0000;
// Now treat the number as positive...
// Get the exponent and limit to 15 bits.
$exponent = (1 + (int) floor(log10($num))) & 0x7FFF;
// Convert the number into a fraction.
$num /= pow(10 , $exponent);
// Now convert the fraction to a 31bit int.
// We don't use the full 32bits, because the -ve numbers
// stuff us up -- this results in better than single
// precision floats, but not as good as double precision.
$fraction = (int) floor($num * 0x7FFFFFFF );
// Pack the number into a 6 byte binary string
* Converts a 6 byte binary string to a single-precision
* @param string $data the binary string to convert
* @return the floating point number
// Extract the sign bit and exponent.
$sign = (($exponent & 0x8000 ) == 0 )? 1 : -1;
// Extract the fractional part.
// Return the reconstructed float.
return $sign * pow(10 , $exponent) * $fraction / 0x7FFFFFFF;
* Bin to string conversion. For example,
* return 'hi' for input of '0110100001101001'.
* @param string $binstring
$binstringreversed = strrev($binstring);
for ($i = 0; $i < strlen($binstringreversed); $i += 8 ) {
* Converts Decimal -> Binary, and left-pads it with $padvalue 0's.
* Bin to dec conversion with fractions.
for ($i = 8; $i--; $i > 0 ) {
$old = ($old + $binRep[$i]) / 2;
* Retrieve native byte order of this OS.
* Little Endian: Intel's 80x86 processors and their clones,
* Big Endian: SPARC, Motorola's 68K, and the PowerPC families.
case "\77\360\0\0\0\0\0\0":
case "\0\0\0\0\0\0\360\77":
// {{{ littleEndianToString
* Little Endian to String conversion.
$intstring = $intstring . chr($number & 127 );
$intstring = $intstring . chr($number & 255 );
* Big Endian to String conversion.
function bigEndianToString($number, $minbytes = 1 , $synchsafe = false , $signed = false )
$maskbyte = (($synchsafe || $signed)? 0x7F : 0xFF );
$number = $number & (0x80 << (8 * ($minbytes - 1 )));
$quotient = ($number / ($maskbyte + 1 ));
$intstring = chr(ceil( ($quotient - floor($quotient)) * $maskbyte)) . $intstring;
$number = floor($quotient);
return str_pad($intstring, $minbytes, chr(0 ), STR_PAD_LEFT );
for ($ret = '', $i = 0; $i < $bytes; $i++ , $val = floor($val / 256 )) {
for ($len = strlen($val), $ret = 0 , $i = 0; $i < $len; $i++ ) {
* Transform bytestring to GUID.
* @param string $byte_str
* @return string GUID string
* Transform GUID to bytestring.
* @param string $guid_str
* @return string byte string
// Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way:
// first 4 bytes are in little-endian order
// next 2 bytes are appended in little-endian order
// next 2 bytes are appended in little-endian order
// next 2 bytes are appended in big-endian order
// next 6 bytes are appended in big-endian order
// AaBbCcDd-EeFf-GgHh-IiJj-KkLlMmNnOoPp is stored as this 16-byte string:
// $Dd $Cc $Bb $Aa $Ff $Ee $Hh $Gg $Ii $Jj $Kk $Ll $Mm $Nn $Oo $Pp
* Little Endian to int conversion.
* @param string $byteword
* Big Endian to int conversion.
* @param string $byteword
function bigEndianToInt($byteword, $synchsafe = false , $signed = false )
$bytewordlen = strlen($byteword);
for ($i = 0; $i < $bytewordlen; $i++ ) {
// disregard MSB, effectively 7-bit bytes
$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F ) << (($bytewordlen - 1 - $i) * 7 );
$intvalue += ord($byteword{$i}) * pow(256 , ($bytewordlen - 1 - $i));
if ($signed && !$synchsafe) {
// synchsafe ints are not allowed to be signed
$signmaskbit = 0x80 << (8 * ($bytewordlen - 1 ));
if ($intvalue & $signmaskbit) {
$intvalue = 0 - ($intvalue & ($signmaskbit - 1 ));
* Little Endian to bin conversion.
* @param string $byteword
* Big Endian to bin conversion.
* @param string $byteword
$bytewordlen = strlen($byteword);
for ($i = 0; $i < $bytewordlen; $i++ ) {
// {{{ littleEndianToFloat
* Little Endian to float conversion.
* @param string $byteword
* @return mixed Either float or false on error
* Big Endian to float conversion.
* @param string $byteword
* @return mixed Either float or false on error
// ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
// http://www.psc.edu/general/software/packages/ieee/ieee.html
// http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
if (strlen($byteword) == 4 ) { // 32-bit DWORD
} else if (strlen($byteword) == 8 ) { // 64-bit QWORD
$exponentstring = substr($bitword, 1 , $exponentbits);
$fractionstring = substr($bitword, 9 , $fractionbits);
if (($exponent == (pow(2 , $exponentbits) - 1 )) && ($fraction != 0 )) {
} else if (($exponent == (pow(2 , $exponentbits) - 1 )) && ($fraction == 0 )) {
$float_val = '-infinity';
$float_val = '+infinity';
} else if (($exponent == 0 ) && ($fraction == 0 )) {
$float_val = ($signbit? 0 : -0 );
} else if (($exponent == 0 ) && ($fraction != 0 )) {
// These are 'unnormalized' values
} else if ($exponent != 0 ) {
return (float) $float_val;
// {{{ floatToBinaryDecimal
* Transform float value to binary decimal.
* @param float $float_val
$maxbits = 128; // to how many bits of precision should the calculations be taken?
$floatpart = abs($float_val - $intpart);
while (($floatpart != 0 ) && (strlen($pointbitstring) < $maxbits)) {
$binarypointnumber = decbin($intpart) . '.' . $pointbitstring;
return $binarypointnumber;
// {{{ normalizeBinaryPoint
* Normalize binary points.
* @param string $binarypointnumber
if (strpos($binarypointnumber, '.') === false ) {
$binarypointnumber = '0.' . $binarypointnumber;
} else if ($binarypointnumber{0 } == '.') {
$binarypointnumber = '0' . $binarypointnumber;
while (($binarypointnumber{0 } != '1') || (substr($binarypointnumber, 1 , 1 ) != '.')) {
if (substr($binarypointnumber, 1 , 1 ) == '.') {
$binarypointnumber = substr($binarypointnumber, 2 , 1 ) . '.' . substr($binarypointnumber, 3 );
$pointpos = strpos($binarypointnumber, '.');
$exponent += ($pointpos - 1 );
$binarypointnumber = str_replace('.', '', $binarypointnumber);
$binarypointnumber = $binarypointnumber{0 } . '.' . substr($binarypointnumber, 1 );
$binarypointnumber = str_pad(substr($binarypointnumber, 0 , $maxbits + 2 ), $maxbits + 2 , '0', STR_PAD_RIGHT );
'normalized' => $binarypointnumber,
'exponent' => (int) $exponent
// {{{ decimalBinaryToFloat
* Transform decimal binary to float.
* @param string $binarynumerator
return ($numerator / $denominator);
for ($i = 0; $i < strlen($string); $i++ ) {
for ($i = 0; $i < strlen($string); $i++ ) {
$ret_str .= ' ' . substr($string, $i, 1 ) . ' ';
* Tuncates a floating-point number at the decimal point
* returns int (if possible, otherwise double)
* @param float $float_val
function _truncate ($float_val)
$truncatednumber = floor($float_val);
} else if ($float_val <= -1 ) {
$truncatednumber = ceil($float_val);
if ($truncatednumber <= pow(2 , 30 )) {
$truncatednumber = (int) $truncatednumber;
* Convert a float to type int, only if possible.
* @param float $float_val
function _castAsInt ($float_val)
// it's not floating point
if ($float_val <= pow(2 , 30 )) {
$float_val = (int) $float_val;
* Converts an int to a binary string, low byte first.
* @param int $num number to convert
* @param int $bytes minimum number of bytes to covert to
* @return string the binary string form of the number
function _decToBin_bytes ($num, $bytes)
for ($i = 0; $i < $bytes; ++ $i) {
$result .= chr($num & 0xFF );
* Converts a binary string to an int, low byte first.
* @param string $str binary string to convert
* @param int $len length of the binary string to convert
* @return int the int version of the binary string
function _binToDec_length (&$str, $len)
for ($i = 0; $i < $len; ++ $i) {
$result |= (@ord($str[$i]) << $shift);
Documentation generated on Mon, 11 Mar 2019 14:30:26 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|