在PERL中有沒有像PHP matchcidr的函式?沒有所以自己寫:
下面的程式檢查你的$ip=163.17.147.1有沒有在你指定的陣列@mysch_ips中
#!/usr/bin/perl -w
use strict;
use Net::IPv4Addr qw( :all );
my( @mysch_ips)= ("163.17.32.0/19","163.17.88.0/21","163.17.96.0/22","163.17.108.0/22",
"163.17.112.0/20","163.17.128.0/23","163.17.130.0/24","163.17.146.0/23",
"163.17.148.0/22","163.17.152.0/21","163.17.160.0/19","163.17.192.0/18");
my $ip="163.17.147.1";
foreach(@mysch_ips){
if (ipv4_in_network( $_, $ip ) ) {
print "Welcome !";
}
}
--
不使用模組的方法來解決這個問題
sub matchcidr{
local $addr= shift;
local $cidr= shift;
local ($ip, $prefix) = split('/', $cidr);
$prefix= 32 if !$prefix;
local $mask = '1' x $prefix . '0' x (32-$prefix);
foreach(@seg){
$ipbin .= &dec2bin($_);
}
if( (&ip2bin($addr)& $mask) eq (&ip2bin($ip)& $mask) ){
return 1;
}else {
return 0;
}
}
sub ip2bin {
local $ip=shift;
local @seg = split('\.',$ip);
local $ipbin ="";
foreach(@seg){
$ipbin .= &dec2bin($_);
}
return $ipbin;
}
sub dec2bin {
my $str = unpack("B32", pack("N", shift));
return sprintf("%08d",$str);
}
叫用
matchcidr( IP, CIDR);
回傳
在CIDR範圍中回傳1,否則回傳0
叫用範例
print &matchcidr('1.2.4.4','1.2.3.0/25'); # 0
print &matchcidr('1.2.3.4','1.2.3.0/25'); # 1
print &matchcidr('1.2.3.4','1.2.3.0'); # 0 未指定 prefix,則比對IP本身是否相同
說明
第6行 把CIDR位址中的prefix轉成二進位的字串,作為遮罩,這裡使用PERL獨有的重覆運算子 'x'
第10行 將轉成二進位字串的兩個位址進行 and 運算,兩者相符就表示同一個網段
第17~25行 把ip變成二進位的字串
第28~31行 把10進位數值變成二進位的字串
相關連結
[PHP] IPv6檢查IP是否在某個網段內 mtachcidr6
原文 2009-12-24 22:53:29 2018.1.6 重寫不用模組方法
此函式我重新整理 2007.10.25 日寫的一段程式作為當時初學perl的紀念,那時為了判斷IP是否為中縣網的IP,中縣網的IP非常散,我寫成一個陣列@mysch_ips,利用一個很棒的函式庫 Net::IPv4Addr ,裡面有一個函式 ipv4_in_network() 來解決這個問題。