MENU

IP地址和CIDR 互转

April 5, 2022 • 已被 434 位童鞋围观过 • 代码分享

ip格式互转

//CIDR格式化结果的列表
function iprange2cidr($ipStart, $ipEnd){
    if (is_string($ipStart) || is_string($ipEnd)){
        $start = ip2long($ipStart);
        $end = ip2long($ipEnd);
    }
    else{
        $start = $ipStart;
        $end = $ipEnd;
    }
    $result = array();
    while($end >= $start){
        $maxSize = 32;
        while ($maxSize > 0){
            $mask = hexdec(iMask($maxSize - 1));
            $maskBase = $start & $mask;
            if($maskBase != $start) break;
            $maxSize--;
        }
        $x = log($end - $start + 1)/log(2);
        $maxDiff = floor(32 - floor($x));
        if($maxSize < $maxDiff){
            $maxSize = $maxDiff;
        }
        $ip = long2ip($start);
        array_push($result, "$ip/$maxSize");
        $start += pow(2, (32-$maxSize));
    }
    return $result;
}
function iMask($s){
    return base_convert((pow(2, 32) - pow(2, (32-$s))), 10, 16);
}


/**
 * 根据网段获取计算所有IP
 * @param string $segment 网段 '139.217.0.1/24'
 * @return array IP列表 ['139.217.0.1','139.217.0.2'……]
 */
function getIpBySegment($segment)
{
    $segmentInfo = explode("/", $segment);//['139.217.0.1',24]
    $beginIpArray = explode(".", $segmentInfo[0]);//[139,217,0,1]
    $mask = intval($segmentInfo['1']);//24
    $endIp = array();
    foreach ($beginIpArray as $ipKey => $item) {
        $beginFlag = 8 * ($ipKey);//0   8   16  24
        $endFlag = 8 * ($ipKey + 1);//8   16  24  32
        $decbinItem = str_pad(decbin($item), 8, "0", STR_PAD_LEFT);
        $endIp[] = $mask >= $endFlag ? $item : ($mask > $beginFlag ? bindec(str_pad(substr($decbinItem, 0, $mask - $beginFlag), 8, "1", STR_PAD_RIGHT)) : ($ipKey <= 2 ? pow(2, 8) - 1 : pow(2, 8) - 1));
    }
    $ipArray = array();
    for ($beginIp[0] = $beginIpArray[0]; $beginIp[0] <= $endIp[0]; $beginIp[0]++) {
        for ($beginIp[1] = $beginIpArray[1]; $beginIp[1] <= $endIp[1]; $beginIp[1]++) {
            for ($beginIp[2] = $beginIpArray[2]; $beginIp[2] <= $endIp[2]; $beginIp[2]++) {
                for ($beginIp[3] = $beginIpArray[3]; $beginIp[3] <= $endIp[3]; $beginIp[3]++) {
                    $ipArray[] = implode(".", $beginIp);
                }
            }
        }
    }
    return $ipArray;
}

Last Modified: September 28, 2023