问题
I'm parsing a binary and stumbled upon some 16bit (2 byte) values that I need to convert from hex to dec and vice versa. Positive values look like this "0075" (117) while negative ones look like that "FE75" (-395).
I'm using this function to convert from hex to signed int, which works, but I can't seem to find a solution for signed int to hex-representation.
function hexdecs($hex)
{
// ignore non hex characters
$hex = preg_replace('/[^0-9A-Fa-f]/', '', $hex);
// converted decimal value:
$dec = hexdec($hex);
// maximum decimal value based on length of hex + 1:
// number of bits in hex number is 8 bits for each 2 hex -> max = 2^n
// use 'pow(2,n)' since '1 << n' is only for integers and therefore limited to integer size.
$max = pow(2, 4 * (strlen($hex) + (strlen($hex) % 2)));
// complement = maximum - converted hex:
$_dec = $max - $dec;
// if dec value is larger than its complement we have a negative value (first bit is set)
return $dec > $_dec ? -$_dec : $dec;
}
回答1:
Thanks for all your comments, I ended up with this and it's just what I wanted.
You're awesome!
/**
* Converts signed decimal to hex (Two's complement)
*
* @param $value int, signed
*
* @param $reverseEndianness bool, if true reverses the byte order (see machine dependency)
*
* @return string, upper case hex value, both bytes padded left with zeros
*/
function signed2hex($value, $reverseEndianness = true)
{
$packed = pack('s', $value);
$hex='';
for ($i=0; $i < 2; $i++){
$hex .= strtoupper( str_pad( dechex(ord($packed[$i])) , 2, '0', STR_PAD_LEFT) );
}
$tmp = str_split($hex, 2);
$out = implode('', ($reverseEndianness ? array_reverse($tmp) : $tmp));
return $out;
}
回答2:
For signed integer use i
and $i < 4;
instead of s
and $i < 2;
.
/**
* Converts signed decimal to hex (Two's complement)
*
* @param $value int, signed
*
* @param $reverseEndianness bool, if true reverses the byte order (see machine dependency)
*
* @return string, upper case hex value, both bytes padded left with zeros
*/
function signed2hex($value, $reverseEndianness = true)
{
$packed = pack('i', $value);
$hex='';
for ($i=0; $i < 4; $i++){
$hex .= strtoupper( str_pad( dechex(ord($packed[$i])) , 2, '0', STR_PAD_LEFT) );
}
$tmp = str_split($hex, 2);
$out = implode('', ($reverseEndianness ? array_reverse($tmp) : $tmp));
return $out;
}
echo signed2hex(-1561800392, false); // 38d1e8a2, not 38d1 with `s`
来源:https://stackoverflow.com/questions/44135572/create-hex-representation-of-signed-int-in-php