ipv4 和 ipv6分段处理方式进行白名单验证
1 <?php 2 /* 3 ipv4 和 ipv6 做分段处理, 这是这次讨论及处理的问题. 4 5 在做ipv4与ipv6分段之前,需要了解ipv4与ipv6的信息. 6 7 ipv4: 8 ipv4 是采用32位2进制编码的, 将32划分为4段, 那么每一段是8位, 例如: 11111111.11111111.00000001.00000001. 而IP表示是通过十进制表示的,例如255.255.1.1 9 10 ipv6: 11 ipv6是采用128位2进制编码的.将128位分为8段,每一段是16位,而IP表示是通过十六进制进行表示的, 例如2001:da8c:ac11:3003:0008:0000:0000:0058 . 12 13 ipv4,ipv6详解,另行查看. 14 15 需求, IP白名单,根据IP区段进行验证. 16 17 分析, ipv4固定的4个段,可以根据区段进行处理. 18 19 假设,添加白名单的ip是,192.168.1.*, 而* 所代表的是0-255, 例如ip是 192.168.1.1 就可以访问.而 192.168.2.* 就不可能访问. 20 21 */ 22 //解决方案. 23 //定义一个IP白名单. 24 $IP_WHITE_LIST = [#IP白名单区段 25 '192.168.1' => [ 26 'start' => '0', 27 'end' => '255', 28 ], 29 ]; 30 31 function checkIpWhiteList ($ip) 32 { 33 $whiteList = $IP_WHITE_LIST; 34 $segment = substr($ip, 0, strirpos($ip, '.')); 35 $intervalVal = substr($ip, strirpos($ip, '.')+1); 36 if(isset($whiteList[$segment])) 37 { 38 if($intervalVal >= $whiteList[$segment]['start'] || $intervalVal <= $whiteList[$segment]['end']) 39 { 40 return true; 41 } 42 } 43 return false; 44 } 45 46 //分析, ipv6不是固定的8个段, 如果是2001:da8c:ac11:3003:0008:0000:0000:0058 就会变成 2001:da8c:ac11:3003:8::58.所以是不是考虑,自己进行填充. 47 48 //解决方案: 49 $IP_WHITE_LIST = [ #IP白名单区段 50 '2001:da8c:ac11:3003:0008:0000:0000' => [ 51 'start' => '0000', 52 'end' => 'ffff', 53 ], 54 ]; 55 56 function checkIpWhiteList ($ip) { 57 $whiteList = $IP_WHITE_LIST; 58 $new_ip = getFullIp($ip); 59 $segment = substr($new_ip, 0, strripos($new_ip, ':')); 60 $intervalVal = substr($new_ip, strripos($new_ip, ':')+1); 61 62 if(isset($whiteList[$segment])) 63 { 64 if(strcmp($intervalVal, $whiteList[$segment]['start']) >= 0 || strcmp($intervalVal, $whiteList[$segment]['end']) <=0) 65 { 66 return true; 67 } 68 } 69 return false; 70 } 71 72 function getFullIp ($ip) 73 { 74 if(!$ip) { 75 return false; 76 } 77 $segmentArr = explode(":", $ip); 78 if('8' == count($segmentArr)) { 79 foreach($segmentArr as &$val) { 80 $val = ('4' == strlen($val)) ? $val: str_pad($val, 4, 0, STR_PAD_LEFT); 81 } 82 } 83 if(count($segmentArr) < '8') { 84 foreach($segmentArr as &$val) { 85 if('' != $val) { 86 $val = ('4' == strlen($val)) ? $val: str_pad($val, 4, 0, STR_PAD_LEFT); 87 }else { 88 $base = '0000'; 89 $difference = (8 - count($segmentArr)) + 1; 90 for($i = 1; $i<=$difference; $i++) 91 { 92 $val .= $base.":"; 93 } 94 $val = trim($val, ':'); 95 } 96 } 97 } 98 return implode(':', $segmentArr); 99 } 100 101 ?>