IpToCidr函数
function ip2cidr($ip_start,$ip_end) { if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return !trigger_error('ip 不合法', E_USER_NOTICE); $ipl_start = ip2long($ip_start); $ipl_end = ip2long($ip_end); if($ipl_start>0 && $ipl_end<0) $delta = ($ipl_end + 4294967296) - $ipl_start; else $delta = $ipl_end - $ipl_start; $netmask = sprintf('%032b', $delta); if(ip2long($ip_start)==0 && substr_count($netmask,"1")==32) return "0.0.0.0/0"; if($delta<0 or ($delta>0 && $delta%2==0)) return !trigger_error("区间数量不合法 $delta", E_USER_NOTICE); for($mask=0; $mask<32; $mask++) if($netmask[$mask]==1) break; if(substr_count($netmask,"0")!=$mask) { $w = strrpos($netmask, '0') + 1; $m = pow(2, 32-$w) - 1; $ip_start = long2ip(($ipl_start & ~$m)+$m+1); return long2ip($ipl_start & ~$m) . "/$w," . ip2cidr($ip_start,$ip_end); }; return "$ip_start/$mask";}
上面是版主大大给写的函数
ip2cidr("36.96.0.0","36.223.255.255")
执行结果36.96.0.0/9
反查
http://www.itmop.com/tool/ipaddress.php
36.96.0.0/9 -> 36.0.0.1 -36.127.255.254 与36.96.0.0 - 36.223.255.255 不一致
有个网站,但是无法看到转换代码
http://ip2cidr.com/
36.96.0.0-36.223.255.255
转化为36.96.0.0/11
36.128.0.0/10
36.192.0.0/11
拆分区间不好掌握。。。
回复讨论(解决方案)
结果结果:可用地址: 8388606掩码: 255.128.0.0网络: 36.96.0.0第一个可用: 36.0.0.1 最后可用: 36.127.255.254 广播: 36.223.255.255
怎么不对啦?
????有??啊。
36.96.0.0/9 -> 36.0.0.1 -36.127.255.254
与36.96.0.0 - 36.223.255.255 不一致
1楼 2楼的 兄弟说完 我以为我手误 结果自己又测试了下 确实ip2cidr("36.96.0.0","36.223.255.255") 执行结果36.96.0.0/9
而36.96.0.0/9 生成IP的区间为 36. 0.0.1 -36. 127.255.254
他那个计算和你的需求是不一样的
他算出的是,在给定的掩码条件下,一个 ip 可以隶属于哪个网段
需求不同,结果也不同
那可能我之前表述错误了 我的需求就是 用函数实现首IP地址和尾IP地址的区间转化为CIDR格式 这样就可以用来查询某个IP地址是否属于这个CIDR区域,其中检验的方法就是用CIDR再反生成首IP地址和尾IP地址的区间。
函数功能类似于http://ip2cidr.com 上的
其实这是 ip2cidr 的 bug
函数的原型来自 php 手册,只是增加了分段的功能
可以看到,分段是在原函数发现做为一段不行的时候进行的
但由于先天不足,他并没有把你的传入不能作为一段判别出来
不知道 这个网站http://ip2cidr.com/ 它是怎么实现的 网上的资源好少
一篇国外的文章用JAVA实现了
import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class RangeToCidr { private static final String IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})"; private static final Pattern addressPattern = Pattern.compile(IP_ADDRESS); public static List<String> rangeToCidrList(String istart, String iend) { int start = toInteger(istart); int end = toInteger(iend); List<String> result = new ArrayList<String>(); while (end >= start) { int maxsize = imaxblock( start, 32); double x = (Math.log(end - start + 1) / Math.log(2) ) ; int maxdiff = (int) (Math.floor(32 - Math.floor(x))); String ip = intToIP(start); if (maxsize < maxdiff) { maxsize = maxdiff; } result.add( ip + "/" + (int)maxsize ); start += Math.pow(2, (32-maxsize)); } return result; } private static int toInteger(String address) { Matcher matcher = addressPattern.matcher(address); if (matcher.matches()) { return matchAddress(matcher); } else throw new IllegalArgumentException("Could not parse [" + address + "]"); } private static int matchAddress(Matcher matcher) { int addr = 0; for (int i = 1; i <= 4; ++i) { int n = (rangeCheck(Integer.parseInt(matcher.group(i)), -1, 255)); addr |= ((n & 0xff) << 8*(4-i)); } return addr; } private static int rangeCheck(int value, int begin, int end) { if (value > begin && value <= end) // (begin,end] return value; throw new IllegalArgumentException("Value [" + value + "] not in range ("+begin+","+end+"]"); } private static String intToIP(int val) { int octets[] = new int[4]; for (int j = 3; j >= 0; --j) octets[j] |= ((val >>> 8*(3-j)) & (0xff)); StringBuilder str = new StringBuilder(); for (int i =0; i < octets.length; ++i){ str.append(octets[i]); if (i != octets.length - 1) { str.append("."); } } return str.toString(); } private static long imask(int t) { return (long)(Math.pow(2, 32) - Math.pow(2, 32-t) ) ; } private static int imaxblock(long ibase, int tbit) { while (tbit > 0) { long im = imask(tbit-1); long imand = ibase & im ; if (imand != ibase) { break; } tbit--; } return tbit; }}
$r = ip2cidr("36.96.0.1","36.223.255.255");print_r($r);function ip2cidr($ip_start,$ip_end) { $res = array(); if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return !trigger_error('ip 不合法', E_USER_NOTICE); $ipl_start = ip2long($ip_start); if($ipl_start < 0) $ipl_start += 0x100000000; $ipl_end = ip2long($ip_end); if($ipl_end<0) $ipl_end += 0x100000000; $ipl=$ipl_start; do { $k = strrpos(sprintf('%032b', $ipl), '1'); $cidr = $k + 1; $dk = pow(2, 32-$k-1); $mask = $dk - 1; $res[] = sprintf("%s/%d", long2ip($ipl & ~$mask), $cidr); $ipl += $dk; }while($ipl < $ipl_end); return $res;}
Array( [0] => 36.96.0.1/32 [1] => 36.96.0.2/31 [2] => 36.96.0.4/30 [3] => 36.96.0.8/29 [4] => 36.96.0.16/28 [5] => 36.96.0.32/27 [6] => 36.96.0.64/26 [7] => 36.96.0.128/25 [8] => 36.96.1.0/24 [9] => 36.96.2.0/23 [10] => 36.96.4.0/22 [11] => 36.96.8.0/21 [12] => 36.96.16.0/20 [13] => 36.96.32.0/19 [14] => 36.96.64.0/18 [15] => 36.96.128.0/17 [16] => 36.97.0.0/16 [17] => 36.98.0.0/15 [18] => 36.100.0.0/14 [19] => 36.104.0.0/13 [20] => 36.112.0.0/12 [21] => 36.128.0.0/9)
还有个更简单的 其中2个函数PHP都有库函数 实测也可以
import java.util.ArrayList;import java.util.List;public class RangeToCidr { public static List<String> range2cidrlist( String startIp, String endIp ) { long start = ipToLong(startIp); long end = ipToLong(endIp); ArrayList<String> pairs = new ArrayList<String>(); while ( end >= start ) { byte maxsize = 32; while ( maxsize > 0) { long mask = CIDR2MASK[ maxsize -1 ]; long maskedBase = start & mask; if ( maskedBase != start ) { break; } maxsize--; } double x = Math.log( end - start + 1) / Math.log( 2 ); byte maxdiff = (byte)( 32 - Math.floor( x ) ); if ( maxsize < maxdiff) { maxsize = maxdiff; } String ip = longToIP(start); pairs.add( ip + "/" + maxsize); start += Math.pow( 2, (32 - maxsize) ); } return pairs; } public static final int[] CIDR2MASK = new int[] { 0x00000000, 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF }; private static long ipToLong(String strIP) { long[] ip = new long[4]; String[] ipSec = strIP.split("\\."); for (int k = 0; k < 4; k++) { ip[k] = Long.valueOf(ipSec[k]); } return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3]; } private static String longToIP(long longIP) { StringBuffer sb = new StringBuffer(""); sb.append(String.valueOf(longIP >>> 24)); sb.append("."); sb.append(String.valueOf((longIP & 0x00FFFFFF) >>> 16)); sb.append("."); sb.append(String.valueOf((longIP & 0x0000FFFF) >>> 8)); sb.append("."); sb.append(String.valueOf(longIP & 0x000000FF)); return sb.toString(); } }
版主大大 看12楼的 JAVA 函数思路 是否可以优化您的代码 以生成3个CIDR 36.96.0.0/11 36.128.0.0/10 36.192.0.0/11
最终让这个函数在PHP沉淀下来 为大家造福
$r = ip2cidr("36.96.0.0","36.223.255.255");print_r($r);
Array( [0] => 36.96.0.0/11 [1] => 36.128.0.0/9)
你给的那个链接,最后一节的结果是错的
您说的是http://ip2cidr.com/ 还是12楼的函数?
确实 36.128.0.0/9 已经超出了36.223.255.255
$r = ip2cidr("36.96.0.0","36.223.255.255");print_r($r);function ip2cidr($ip_start,$ip_end) { $res = array(); if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return !trigger_error('ip 不合法', E_USER_NOTICE); $ipl_start = ip2long($ip_start); if($ipl_start < 0) $ipl_start += 0x100000000; $ipl_end = ip2long($ip_end); if($ipl_end<0) $ipl_end += 0x100000000; $ipl=$ipl_start; do { $k = strrpos(sprintf('%032b', $ipl), '1'); $cidr = $k + 1; $dk = pow(2, 32-$k-1); if($ipl + $dk > $ipl_end) { $dk /= 2; $cidr++; } $mask = $dk - 1; $res[] = sprintf("%s/%d", long2ip($ipl & ~$mask), $cidr); $ipl += $dk; }while($ipl < $ipl_end); return $res;}
Array( [0] => 36.96.0.0/11 [1] => 36.128.0.0/10 [2] => 36.192.0.0/11)
我试试不同的IP地址段 做个测试
拆的好开呀。。。 版主大大 看看 还能优化下吗
$ip_st = "103.233.183.0";$ip_end = "103.233.183.255";print $ip_st."-".$ip_end."<br>";$cidr_arr = ip2cidr($ip_st,$ip_end );print_r($cidr_arr);print "<br>";for($i = 0 ; $i < count($cidr_arr); $i++){ print $cidr_arr[$i]." : "; print cidr_conv($cidr_arr[$i])."<br>"; }
103.233.183.0-103.233.183.255
Array ( [0] => 103.233.183.0/25 [1] => 103.233.183.128/26 [2] => 103.233.183.192/27 [3] => 103.233.183.224/28 [4] => 103.233.183.240/29 [5] => 103.233.183.248/30 [6] => 103.233.183.252/31 [7] => 103.233.183.254/32 )
103.233.183.0/25 : 103.233.183.0 - 103.233.183.127
103.233.183.128/26 : 103.233.183.128 - 103.233.183.191
103.233.183.192/27 : 103.233.183.192 - 103.233.183.223
103.233.183.224/28 : 103.233.183.224 - 103.233.183.239
103.233.183.240/29 : 103.233.183.240 - 103.233.183.247
103.233.183.248/30 : 103.233.183.248 - 103.233.183.251
103.233.183.252/31 : 103.233.183.252 - 103.233.183.253
103.233.183.254/32 : 103.233.183.254 - 103.233.183.254
function cidr_conv($cidr_address) { $first = substr($cidr_address, 0, strpos($cidr_address, "/")); $netmask = substr(strstr($cidr_address, "/"), 1); $first_bin = str_pad(decbin(ip2long($first)), 32, "0", STR_PAD_LEFT); $netmask_bin = str_pad(str_repeat("1", (integer)$netmask), 32, "0", STR_PAD_RIGHT); for ($i = 0; $i < 32; $i++) { if ($netmask_bin[$i] == "1") $last_bin .= $first_bin[$i]; else $last_bin .= "1"; } $last = long2ip(bindec($last_bin)); return "$first - $last";}
$r = ip2cidr("103.233.183.0", "103.233.183.255");print_r($r);function ip2cidr($ip_start,$ip_end) { $res = array(); if(long2ip(ip2long($ip_start))!=$ip_start or long2ip(ip2long($ip_end))!=$ip_end) return !trigger_error('ip 不合法', E_USER_NOTICE); $ipl_start = ip2long($ip_start); if($ipl_start < 0) $ipl_start += 0x100000000; $ipl_end = ip2long($ip_end); if($ipl_end<0) $ipl_end += 0x100000000; $ipl=$ipl_start; do { $k = strrpos(sprintf('%032b', $ipl), '1'); $cidr = $k + 1; $dk = pow(2, 32-$k-1); if($ipl + $dk > $ipl_end + 1) { $dk /= 2; $cidr++; } $mask = $dk - 1; $res[] = array( 'cidr' => sprintf("%s/%d", long2ip($ipl & ~$mask), $cidr), 'mask' => long2ip(~$mask), 'net' => long2ip($ipl & ~$mask), 'usable' => $mask - 1, 'start' => long2ip(($ipl & ~$mask) + 1), 'end' => long2ip(($ipl | $mask) - 1), 'broadcast' => long2ip($ipl | $mask), ); $ipl += $dk; }while($ipl < $ipl_end); return $res;}
Array( [0] => Array ( [cidr] => 103.233.183.0/24 [mask] => 255.255.255.0 [net] => 103.233.183.0 [usable] => 254 [start] => 103.233.183.1 [end] => 103.233.183.254 [broadcast] => 103.233.183.255 ))
$r = ip2cidr("210.80.0.0", "210.80.63.255");
print_r($r);
Array
(
[0] => Array
(
[cidr] => 210.80.0.0/13
[mask] => 255.248.0.0
[net] => 210.80.0.0
[usable] => 524286
[start] => 210.80.0.1
[end] => 210.87.255.254
[broadcast] => 210.87.255.255
)
)
这块就存在BUG了 您看下12楼的方法是否合适
最终函数:
$CIDR2MASK = array( 0x00000000, 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF ); function ipTocidr($ip_start,$ip_end) { global $CIDR2MASK; $StartIp = ip2long($ip_start); $EndIp = ip2long($ip_end); $pairs = array(); while ( $EndIp >= $StartIp ) { $maxsize = 32; while ( $maxsize > 0) { $mask = $CIDR2MASK[$maxsize-1]; $maskedBase = $StartIp & $mask ; if ( $maskedBase != $StartIp ) { break; } $maxsize--; } $x = log( $EndIp - $StartIp + 1) / log(2); $maxdiff = 32 - floor($x) ; if ( $maxsize < $maxdiff) { $maxsize = $maxdiff; } $ip = long2ip($StartIp); $pairs[] = $ip."/".$maxsize; $StartIp += pow( 2, (32 - $maxsize) ); } return $pairs; }
谢谢版主大大的悉心指导,最后还是将JAVA的函数翻译了

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Die Go-Sprache bietet zwei Technologien zur dynamischen Funktionserstellung: Schließung und Reflexion. Abschlüsse ermöglichen den Zugriff auf Variablen innerhalb des Abschlussbereichs, und durch Reflektion können mithilfe der FuncOf-Funktion neue Funktionen erstellt werden. Diese Technologien sind nützlich bei der Anpassung von HTTP-Routern, der Implementierung hochgradig anpassbarer Systeme und dem Aufbau steckbarer Komponenten.

Bei der Benennung von C++-Funktionen ist es wichtig, die Reihenfolge der Parameter zu berücksichtigen, um die Lesbarkeit zu verbessern, Fehler zu reduzieren und das Refactoring zu erleichtern. Zu den gängigen Konventionen für die Parameterreihenfolge gehören: Aktion-Objekt, Objekt-Aktion, semantische Bedeutung und Einhaltung der Standardbibliothek. Die optimale Reihenfolge hängt vom Zweck der Funktion, den Parametertypen, möglichen Verwirrungen und Sprachkonventionen ab.

Der Schlüssel zum Schreiben effizienter und wartbarer Java-Funktionen ist: Halten Sie es einfach. Verwenden Sie eine aussagekräftige Benennung. Bewältigen Sie besondere Situationen. Nutzen Sie entsprechende Sichtbarkeit.

Zu den Vorteilen von Standardparametern in C++-Funktionen gehören die Vereinfachung von Aufrufen, die Verbesserung der Lesbarkeit und die Vermeidung von Fehlern. Die Nachteile sind eingeschränkte Flexibilität und Namensbeschränkungen. Zu den Vorteilen variadischer Parameter gehören unbegrenzte Flexibilität und dynamische Bindung. Zu den Nachteilen gehören eine größere Komplexität, implizite Typkonvertierungen und Schwierigkeiten beim Debuggen.

1. Die SUMME-Funktion wird verwendet, um die Zahlen in einer Spalte oder einer Gruppe von Zellen zu summieren, zum Beispiel: =SUMME(A1:J10). 2. Die Funktion AVERAGE wird verwendet, um den Durchschnitt der Zahlen in einer Spalte oder einer Gruppe von Zellen zu berechnen, zum Beispiel: =AVERAGE(A1:A10). 3. COUNT-Funktion, die verwendet wird, um die Anzahl der Zahlen oder Texte in einer Spalte oder einer Gruppe von Zellen zu zählen, zum Beispiel: =COUNT(A1:A10) 4. IF-Funktion, die verwendet wird, um logische Urteile auf der Grundlage spezifizierter Bedingungen zu treffen und die zurückzugeben entsprechendes Ergebnis.

Zu den Vorteilen von Funktionen, die Referenztypen in C++ zurückgeben, gehören: Leistungsverbesserungen: Durch die Übergabe als Referenz wird das Kopieren von Objekten vermieden, wodurch Speicher und Zeit gespart werden. Direkte Änderung: Der Aufrufer kann das zurückgegebene Referenzobjekt direkt ändern, ohne es neu zuzuweisen. Einfachheit des Codes: Die Übergabe als Referenz vereinfacht den Code und erfordert keine zusätzlichen Zuweisungsvorgänge.

Der Unterschied zwischen benutzerdefinierten PHP-Funktionen und vordefinierten Funktionen ist: Umfang: Benutzerdefinierte Funktionen sind auf den Umfang ihrer Definition beschränkt, während auf vordefinierte Funktionen im gesamten Skript zugegriffen werden kann. So definieren Sie: Benutzerdefinierte Funktionen werden mit dem Schlüsselwort function definiert, während vordefinierte Funktionen vom PHP-Kernel definiert werden. Parameterübergabe: Benutzerdefinierte Funktionen empfangen Parameter, während vordefinierte Funktionen möglicherweise keine Parameter erfordern. Erweiterbarkeit: Benutzerdefinierte Funktionen können nach Bedarf erstellt werden, während vordefinierte Funktionen integriert sind und nicht geändert werden können.

Die Ausnahmebehandlung in C++ kann durch benutzerdefinierte Ausnahmeklassen verbessert werden, die spezifische Fehlermeldungen und Kontextinformationen bereitstellen und benutzerdefinierte Aktionen basierend auf dem Fehlertyp ausführen. Definieren Sie eine von std::Exception geerbte Ausnahmeklasse, um spezifische Fehlerinformationen bereitzustellen. Verwenden Sie das Schlüsselwort throw, um eine benutzerdefinierte Ausnahme auszulösen. Verwenden Sie „dynamic_cast“ in einem Try-Catch-Block, um die abgefangene Ausnahme in einen benutzerdefinierten Ausnahmetyp zu konvertieren. Im tatsächlichen Fall löst die Funktion open_file eine FileNotFoundException-Ausnahme aus. Das Abfangen und Behandeln der Ausnahme kann eine spezifischere Fehlermeldung liefern.
