我試圖在C中用PHP編寫以下函數。問題是,用PHP編寫的函數返回的結果與C中返回的結果不同。將嵌入式C函數轉換爲PHP函數
我認爲問題來自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;
}
PHP函數:
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;
}
謝謝。
SOLUTION:
我發現一種解決方案:下面的代碼使用的功能,其允許做無符號的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;
}
謝謝你的回答。
發佈您的PHP代碼到目前爲止 –
如果它是一個已知的密碼,可能您可以在PHP的[密碼擴展]中找到它(http://es2.php.net/manual/en/refs.crypto.php ) –