Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将嵌入式C函数转换为PHP函数_Php_C_Function_Unsigned Integer - Fatal编程技术网

将嵌入式C函数转换为PHP函数

将嵌入式C函数转换为PHP函数,php,c,function,unsigned-integer,Php,C,Function,Unsigned Integer,我正试图在PHP中“翻译”以下用C编写的函数。问题是,用PHP编写的函数返回的结果与用C编写的函数返回的结果不同 我认为问题来自PHP中的整数溢出,它不能将变量视为无符号32位整数 我试图用0xFFFFFFFF屏蔽所有操作,但没有成功。你有其他可行的解决方案吗 C函数: void decipher(const uint32_t num_rounds, uint32_t v[2], const uint32_t key[4]) { uint32_t idx; uint32_t v0

我正试图在PHP中“翻译”以下用C编写的函数。问题是,用PHP编写的函数返回的结果与用C编写的函数返回的结果不同

我认为问题来自PHP中的整数溢出,它不能将变量视为无符号32位整数

我试图用0xFFFFFFFF屏蔽所有操作,但没有成功。你有其他可行的解决方案吗

C函数:

void
decipher(const uint32_t num_rounds, uint32_t v[2], const uint32_t key[4])
{
    uint32_t idx;
    uint32_t v0 = v[0];
    uint32_t v1 = v[1];
    uint32_t delta = 0x9E3779B9;
    uint32_t sum = delta * num_rounds;

    for (idx = 0; idx < num_rounds; ++idx)
    {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }

    v[0] = v0;
    v[1] = v1;
}
function decipher($num_rounds, &$v, $key)
{
    $v0 = $v[0];
    $v1 = $v[1];
    $delta = 0x9E3779B9;
    $sum = ($delta * $num_rounds) & 0xFFFFFFFF;

    for ($idx = 0; $idx < $num_rounds; ++$idx)
    {
        $v1 -= (((($v0 << 4) ^ ($v0 >> 5)) + $v0) ^ ($sum + $key[($sum >> 11) & 3])) & 0xFFFFFFFF;
        $v1 &= 0xFFFFFFFF;
        $sum -= $delta;
        $sum &= 0xFFFFFFFF;
        $v0 -= ((($v1 << 4) ^ ($v1 >> 5) + $v1) ^ ($sum + $key[$sum & 3])) & 0xFFFFFFFF;
        $v0 &= 0xFFFFFFFF;
    }

    $v[0] = $v0;
    $v[1] = $v1;
}
void
解密(const uint32_t num_rounds,uint32_t v[2],const uint32_t key[4])
{
uint32_t idx;
uint32_t v0=v[0];
uint32_t v1=v[1];
uint32_t delta=0x9E3779B9;
uint32\u t总和=增量*轮数;
对于(idx=0;idx5))+v0)^(和+键[(和>>11)和3]);
总和-=增量;
v0-=((v1>5))+v1^(sum+key[sum&3]);
}
v[0]=v0;
v[1]=v1;
}
PHP函数:

void
decipher(const uint32_t num_rounds, uint32_t v[2], const uint32_t key[4])
{
    uint32_t idx;
    uint32_t v0 = v[0];
    uint32_t v1 = v[1];
    uint32_t delta = 0x9E3779B9;
    uint32_t sum = delta * num_rounds;

    for (idx = 0; idx < num_rounds; ++idx)
    {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }

    v[0] = v0;
    v[1] = v1;
}
function decipher($num_rounds, &$v, $key)
{
    $v0 = $v[0];
    $v1 = $v[1];
    $delta = 0x9E3779B9;
    $sum = ($delta * $num_rounds) & 0xFFFFFFFF;

    for ($idx = 0; $idx < $num_rounds; ++$idx)
    {
        $v1 -= (((($v0 << 4) ^ ($v0 >> 5)) + $v0) ^ ($sum + $key[($sum >> 11) & 3])) & 0xFFFFFFFF;
        $v1 &= 0xFFFFFFFF;
        $sum -= $delta;
        $sum &= 0xFFFFFFFF;
        $v0 -= ((($v1 << 4) ^ ($v1 >> 5) + $v1) ^ ($sum + $key[$sum & 3])) & 0xFFFFFFFF;
        $v0 &= 0xFFFFFFFF;
    }

    $v[0] = $v0;
    $v[1] = $v1;
}
函数解密($num_轮,&$v,$key)
{
$v0=$v[0];
$v1=$v[1];
$delta=0x9E3779B9;
$sum=($delta*$num_轮)&0xFFFFFFFF;
对于($idx=0;$idx<$num_轮;++$idx)
{
$v1-=(($v0>5))+$v0^($sum+$key[($sum>>11)和3])和0xffffff;
$v1&=0xFFFFFFFF;
$sum-=$delta;
$sum&=0xFFFFFFFF;
$v0-=(($v1>5)+$v1)^($sum+$key[$sum&3])&0xFFFFFFFF;
$v0&=0xFFFFFFFF;
}
$v[0]=$v0;
$v[1]=$v1;
}
多谢各位

解决方案: 我找到了一个解决方案:下面的代码使用函数,允许对无符号32位整数执行移位操作和加法

function decipher($num_rounds, &$v, $key)
{
    $v0 = $v[0];
    $v1 = $v[1];
    $delta = 0x9E3779B9;
    $sum = ($delta * $num_rounds) & 0xFFFFFFFF;

    for ($idx = 0; $idx < $num_rounds; ++$idx)
    {   
        $v1 = _add($v1, -(_add($v0 << 4 ^ _rshift($v0, 5), $v0) ^ _add($sum, $key[_rshift($sum, 11) & 3])));
        $sum = _add($sum, -$delta);
        $v0 = _add($v0, -(_add($v1 << 4 ^ _rshift($v1, 5), $v1) ^ _add($sum, $key[$sum & 3])));
    }

    $v[0] = $v0;
    $v[1] = $v1;
}

function _rshift($integer, $n)
{
    // convert to 32 bits
    if (0xffffffff < $integer || -0xffffffff > $integer)
    {
        $integer = fmod($integer, 0xffffffff + 1);
    }

    // convert to unsigned integer
    if (0x7fffffff < $integer) {
        $integer -= 0xffffffff + 1.0;
    }
    else if (-0x80000000 > $integer)
    {
        $integer += 0xffffffff + 1.0;
    }

    // do right shift
    if (0 > $integer)
    {
        // remove sign bit before shift
        $integer &= 0x7fffffff;
        // right shift
        $integer >>= $n;
        // set shifted sign bit
        $integer |= 1 << (31 - $n);
    }
    else
    {
        // use normal right shift
        $integer >>= $n;
    }

    return $integer;
}


function _add($i1, $i2)
{
    $result = 0.0;

    foreach (func_get_args() as $value)
    {
        // remove sign if necessary
        if (0.0 > $value)
        {
            $value -= 1.0 + 0xffffffff;
        }

        $result += $value;
    }

    // convert to 32 bits
    if (0xffffffff < $result || -0xffffffff > $result)
    {
        $result = fmod($result, 0xffffffff + 1);
    }

    // convert to signed integer
    if (0x7fffffff < $result)
    {
        $result -= 0xffffffff + 1.0;
    }
    else if (-0x80000000 > $result)
    {
        $result += 0xffffffff + 1.0;
    }

    return $result;
}
函数解密($num_轮,&$v,$key)
{
$v0=$v[0];
$v1=$v[1];
$delta=0x9E3779B9;
$sum=($delta*$num_轮)&0xFFFFFFFF;
对于($idx=0;$idx<$num_轮;++$idx)
{   
$v1=_add($v1,-(_add($v0$integer)
{
$integer+=0xFFFFFF+1.0;
}
//右移
如果(0>$integer)
{
//换班前取下标志位
$integer&=0x7fffffff;
//右移
$integer>>=$n;
//设置移位符号位
$integer |=1>=$n;
}
返回$integer;
}
函数_添加($i1,$i2)
{
$result=0.0;
foreach(func_get_args()作为$value)
{
//如有必要,移除标志
如果(0.0>$value)
{
$value-=1.0+0xffffffff;
}
$result+=$value;
}
//转换为32位
如果(0xFFFFFF<$result | |-0xFFFFFF>$result)
{
$result=fmod($result,0xffffffff+1);
}
//转换为有符号整数
如果(0x7fffffff<$result)
{
$result-=0xFFFFFF+1.0;
}
否则如果(-0x8000000>$result)
{
$result+=0xffffffff+1.0;
}
返回$result;
}

感谢您的回答。

如果您需要在PHP中使用非常大的整数进行数学运算,您的选择基本上是使用字符串和您选择的任意精度库:


在这种情况下,GMP是您唯一的选择,因为另一个库不支持按位操作。

到目前为止也发布您的PHP代码。如果它是已知的密码,您可以在PHP中找到它,也可以从PHP运行您的C函数。所有整数必须限制为32位。您所说的“非常大的整数”是什么意思?“非常大”是指“越大越好”。例如,2147483648。有关适合的详细信息,请参阅
PHP_INT_MAX
PHP_INT_SIZE
常量。