PHP - よく使う関数 - ネットワーク - ip2long


 クラウディア


1. 概要
2. 基本
3. CIDR 形式へ変換
4. アドレス範囲内かチェック
5. 参考サイト

1. 概要

 「ip2long()」は、ドット表記の (IPv4) IP アドレスの文字列を、長整数表現に変換します。

2. 基本

 基本的な使い方は、下記の通りです。

ip2long(string $ip): int | false
 正常時は、返還後の長整数が返ります。  入力引数が、不正な時は、「false」が返ります。

3. CIDR 形式へ変換

 アドレス範囲を指定して、「CIDR」形式に変換するには、下記のように記述します。

function ipRangeToCidr($startIp, $endIp)
{
    $start = ip2long($startIp);
    $end   = ip2long($endIp);

    $cidrList = [];

    while ($end >= $start)
	{
        $maxSize = 32;

        // 最小のブロックサイズを探す
        while ($maxSize > 0)
		{
            $mask = (1 << (32 - ($maxSize - 1))) - 1;
            if (($start & $mask) != 0) {
                break;
            }
            $maxSize--;
        }

        // 終了IPを超えない最大のブロックサイズを探す
        $x = log($end - $start + 1) / log(2);
        $maxDiff = 32 - floor($x);

        if ($maxSize < $maxDiff)
		{
            $maxSize = $maxDiff;
        }

        $cidrList[] = long2ip($start) . "/" . $maxSize;
        $start += pow(2, (32 - $maxSize));
    }

    return $cidrList;
}
 上記の関数を利用して、確認してみます。  下記のソースを記述して。

<?php

... ここに 上記関数を記述 ...

$startIp = "192.168.0.0";
$endIp   = "192.168.255.255";

$result = ipRangeToCidr($startIp, $endIp);

print_r($result);
 実行すると、下記の結果が得られます。

Array
(
    [0] => 192.168.0.0/16
)

4. アドレス範囲内かチェック

 「ChatGPT」くんに、「php で、ある ipv4 のアドレスが cidr で示す、ネットワークアドレス内にあるかどうか判断する処理は作れますか?」と質問したら。  下記のようなコードを教えてくれました。

<?php
/**
 * 指定したIPアドレスがCIDR範囲内に含まれているかを判定
 *
 * @param string $ip    判定したいIPv4アドレス (例: "192.168.1.10")
 * @param string $cidr  CIDR表記ネットワーク (例: "192.168.1.0/24")
 * @return bool         true: 含まれている / false: 含まれていない
 */
function ipv4_in_cidr(string $ip, string $cidr): bool
{
    // CIDRを分解
    [$subnet, $maskBits] = explode('/', $cidr);

    // IPを整数に変換
    $ipLong = ip2long($ip);
    $subnetLong = ip2long($subnet);

    // マスクを作成
    $mask = -1 << (32 - (int)$maskBits);
    $mask = $mask & 0xFFFFFFFF; // 32bit 符号なしに変換

    // 判定
    return ($ipLong & $mask) === ($subnetLong & $mask);
}
 この関数を利用して、確認してみます。

$cidr = "192.168.1.0/24";

print("cidr[$cidr]".PHP_EOL);

$addr = "192.168.1.10";

if (ipv4_in_cidr($addr, $cidr))
{
	print("addr[$addr] is in cidr".PHP_EOL);
} else
{
	print("addr[$addr] is NOT in cidr".PHP_EOL);
}

$addr = "192.168.2.10";

if (ipv4_in_cidr($addr, $cidr))
{
	print("addr[$addr] is in cidr".PHP_EOL);
} else
{
	print("addr[$addr] is NOT in cidr".PHP_EOL);
}
 これを実行すると以下の結果が得られます。

cidr[192.168.1.0/24]
addr[192.168.1.10] is in cidr
addr[192.168.2.10] is NOT in cidr

5. 参考サイト

 本ページは、下記のサイトおよび「ChatGPT」くんを参考にさせていただきました。
PHP: ip2long - Manual

AbemaTV 無料体験
Amazonギフトカード