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」