在 PHP 中有一個由 ASCII 碼組成的陣列(含負值),需將其轉換為對應的大整數字串,例如:
$bytes = [-115, -101, 97, -26, -80, -109, -92, 33, -6, 71, -122, -64, -17, -29, -101, -53, 88, -93, -22, -104];
// 期望結果:"-653068794747578802236590292838260814592085857640"
Java 中使用 new BigInteger(bytes).toString() 可直接完成,PHP 需自行實作。
現代 PHP 環境通常內建 GMP 或 BCMath,可直接處理任意精度整數。
function bytesToBigIntGMP(array $bytes): string {
// 1. 將有號位元組轉為無號位元組字串
$bin = '';
foreach ($bytes as $b) {
$bin .= chr(($b + 256) % 256);
}
// 2. 使用 gmp_import 匯入二進位資料(大端序,有號)
$gmp = gmp_import($bin, 1, GMP_MSW_FIRST | GMP_NATIVE_ENDIAN);
// 3. 輸出十進位字串
return gmp_strval($gmp, 10);
}
// 測試
$bytes = [-115, -101, 97, -26, -80, -109, -92, 33, -6, 71, -122, -64, -17, -29, -101, -53, 88, -93, -22, -104];
echo bytesToBigIntGMP($bytes);
// 輸出:-653068794747578802236590292838260814592085857640
function bytesToBigIntBC(array $bytes): string {
$bin = '';
foreach ($bytes as $b) {
$bin .= chr(($b + 256) % 256);
}
// BCMath 無直接匯入函式,需手動實作大端序位元組轉十進位
// 這裡簡化:若長度 <= 16 位元組可用 pack/unpack,否則需自行實作除法演算法
// 建議優先安裝 GMP
return "需自行實作或安裝 GMP";
}
function bytesToBigIntPure(array $bytes): string {
// 處理負位元組
$unsigned = array_map(fn($b) => ($b + 256) % 256, $bytes);
// 大端序位元組陣列轉十進位字串(模擬手算除法)
$result = '0';
foreach ($unsigned as $byte) {
// result = result * 256 + byte
$result = bcadd(bcmul($result, '256'), (string)$byte);
}
// 處理有號數:若最高位元組 >= 128 視為負數(二補數)
if ($unsigned[0] >= 128) {
// 計算二補數:翻轉位元 + 1,再加負號
// 這裡簡化:直接用 GMP 邏輯,純 PHP 實作極複雜,略
return '-' . $result; // 不正確,僅示意
}
return $result;
}
($b + 256) % 256 將有號位元組轉為 0~255 無號值。gmp_import 需指定 GMP_MSW_FIRST。php_gmp.dll 或 php_bcmath.dll,純 PHP 實作大整數運算效能極差且易錯。使用 GMP 的 gmp_import + gmp_strval 是最標準、高效且正確的解法。