Create hex-representation of signed int in PHP

眉间皱痕 提交于 2021-02-08 10:18:31

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!