|
Follow @phpsnips |
/**
* input $limits array or yii object of IP addresses sorted by SQL server
* returns array of aggregated prefixes and netmask lengths (aka masklen)
*/
function _viewAggregate($limits) { // input addresses must be sorted ascending
$input = $output = array();
$index = 0;
foreach( $limits as $l ) { // fix pure IPs without prefix, prepare array of prefixes
$n = explode ("/",$l->address, 1);
if (empty($n[1])) // optionally fix host mask = /32
$n[1] = 32;
$net['prefix'] = $n[0];
$net['masklen'] = $n[1];
$net['version'] = (8*strlen($net['prefix']) == 128 ) ? 6 : 4; // detect IP prefix version (6 or 4)
$net['index'] = $index;
$input[$index++] = $net; // pure array of prefixes with extra info
}
$reductions = 1; $iteration = 0;
while($reductions > 0) {
$iteration++;
$reductions = $skipNext = 0;
$output = array();
foreach( array_keys($input) as $key ) {
if ($skipNext) {
$skipNext = false;
continue;
}
$i = $input[$key];
$prefixWithoutMask = ($i['version']==4) ? ip2long($i['prefix']) >> (32-$i['masklen']) : ip2long6($i['prefix']) >> (128-$i['masklen']);
if (!empty($input[1+$key])) {
$next = $input[1+$key];
} else continue; // skip the last element
$nextPrefixWithoutMask = ($next['version']==4) ? ip2long($next['prefix']) >> (32-$next['masklen']) : ip2long6($next['prefix']) >> (128-$next['masklen']);
if ( ($i['masklen'] == $next['masklen']) // neighbouring prefixes are of the same length
AND ($nextPrefixWithoutMask - $prefixWithoutMask === 1) // prefixes differ by 1 in the last digit
AND (($prefixWithoutMask >> 1) === ($nextPrefixWithoutMask >> 1)) ) { // higher bits are equal
$i['masklen']--; // aggregate with the next record
$skipNext = true;
$reductions++;
}
$output[] = $i;
}
$input = array_merge(array(), $output); // renumber the array index/key
}
return $input;
}
function _viewMaskLengthToMask($len) { // ipv4 only
if ($len <= 32)
return long2ip(((1 << (32-$len)) - 1));
}
function ip2long6($ipv6) {
$ip_n = inet_pton($ipv6);
$bits = 15; // 16 x 8 bit = 128bit
while ($bits >= 0) {
$bin = sprintf("%08b",(ord($ip_n[$bits])));
$ipv6long = $bin.$ipv6long;
$bits--;
}
return gmp_strval(gmp_init($ipv6long,2),10);
}
function long2ip6($ipv6long) {
$bin = gmp_strval(gmp_init($ipv6long,10),2);
if (strlen($bin) < 128) {
$pad = 128 - strlen($bin);
for ($i = 1; $i <= $pad; $i++) {
$bin = "0".$bin;
}
}
$bits = 0;
while ($bits <= 7) {
$bin_part = substr($bin,($bits*16),16);
$ipv6 .= dechex(bindec($bin_part)).":";
$bits++;
}
// compress
return inet_ntop(inet_pton(substr($ipv6,0,-1)));
}
|
Rate this Snippet: |
Suggested Difficulty Level: Professional
Current Score: No votes yet
Total Views: 218
Other top snippets by synapse:
1. Shorten text and (4 of 1)
2. file-based simple guest (0 of 0)
3. adding an entry (0 of 0)
4. integer to currency (1.33 of 3)
5. Aggregate IP addresses (0 of 0)
6. file handling (0 of 0)
7. testing system with (0 of 0)
8. Make an php (1 of 1)
9. allow download in (5 of 1)
10. redirect in 3 (0 of 0)
11. live clock with (0 of 0)
12. visit counter (3.5 of 2)
13. contact form with (4 of 1)
14. show a specific (0 of 0)
15. The & sign (0 of 0)
16. static variable in (0 of 0)
17. multiplication table with (0 of 0)
18. function with multiplicationt (0 of 0)
19. php generated menu (0 of 0)
20. drawing a table (0 of 0)
21. embedded array (one (0 of 0)
22. checks the week (0 of 0)
23. put links on (4.5 of 2)
24. Directory Image Gallery (0 of 0)
25. TOS (4 of 1)