首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

深度解析 PHP ip2long 與 long2ip:IPv4 地址與整數互轉原理與實現

     編輯:PHP 相關知識

前言

IPv4 地址(如 12.34.56.78)本質是 32 位無符號整數。PHP 內建 ip2long() 與 long2ip() 實現互轉,理解其位運算原理有助於處理 IP 段範圍查詢、數據庫存儲優化等場景。

核心原理:位移與掩碼

將四段八位組合為 32 位整數:

$ip = '12.34.56.78';
$parts = explode('.', $ip);

// 手動計算:每段左移對應位數再相加
$long = ($parts[0] << 24) + ($parts[1] << 16) + ($parts[2] << 8) + $parts[3];
// 結果:203569230

// 驗證內建函數
echo ip2long($ip);      // 203569230
echo long2ip($long);    // 12.34.56.78

反向轉換:整數還原 IP

利用位掩碼 & 0xFF 取出每 8 位:

function long2ip_manual(int $long): string {
    return implode('.', [
        ($long >> 24) & 0xFF,
        ($long >> 16) & 0xFF,
        ($long >> 8)  & 0xFF,
        $long & 0xFF,
    ]);
}

echo long2ip_manual(203569230); // 12.34.56.78

有符號整數陷阱

PHP 整數是有符號的,32 位最高位為符號位。當 IP 首段 ≥ 128 時,ip2long() 返回負數。

$ip = '255.255.255.255';
echo ip2long($ip); // -1 (32 位系統) 或 4294967295 (64 位系統)

// 統一獲取無符號值
printf('%u', ip2long($ip)); // 4294967295

實際應用場景

  1. 數據庫存儲:用 INT UNSIGNED 存 IP,節省空間且利於範圍查詢(`BETWEEN`)。
  2. IP 段匹配:將 CIDR 轉換為起止整數,判斷 IP 是否在範圍內。
    function ipInCidr(string $ip, string $cidr): bool {
        [$range, $bits] = explode('/', $cidr);
        $mask = ~((1 << (32 - $bits)) - 1);
        $ipLong = ip2long($ip);
        $rangeLong = ip2long($range);
        return ($ipLong & $mask) === ($rangeLong & $mask);
    }
  3. 邀請碼/短鏈接生成:將自增 ID 經位運算混淆為短字符串,解碼時反向操作。

總結

掌握 IP 與長整數互轉的位運算細節,能編寫更高效、更安全的網絡相關代碼。記住在 32 位環境處理負數問題,生產環境建議統一用 sprintf('%u', ...) 或 64 位 PHP。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved