Skip to content

Instantly share code, notes, and snippets.

@andersonfraga
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andersonfraga/7ac58b8bfd72a23ce4d6 to your computer and use it in GitHub Desktop.
Save andersonfraga/7ac58b8bfd72a23ce4d6 to your computer and use it in GitHub Desktop.
Busca a menor máscara possível em uma lista de CIDRs
<?php
class IPv4Subnet
{
private $address, $mask;
function __construct($ip)
{
list($this->address, $this->mask) = $this->toBin($ip);
}
public function within($ip)
{
list($subjectAddress, $subjectMask) = $this->toBin($ip);
return $this->mask !== $subjectMask &&
($this->mask | ($this->mask ^ $subjectMask)) === $this->mask &&
($this->address & $subjectMask) === $subjectAddress;
}
private function toBin($ip)
{
preg_match('#([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\/([0-9]+)#is', $ip, $bytes);
$base = ~((~0 << 16) << 16);
$mask = $base << (32 - $bytes[5]);
$mask = pack('C*', $mask >> 24 & 0xFF, $mask >> 16 & 0xFF, $mask >> 8 & 0xFF, $mask & 0xFF);
$address = pack('C*', $bytes[1], $bytes[2], $bytes[3], $bytes[4]) & $mask;
return [$address, $mask];
}
}
$list = file('list.txt');
$result = [];
foreach ($list as $ip) {
$cidr = new IPv4Subnet($ip);
$result[$ip] = 1;
foreach ($list as $compare) {
if ($cidr->within($compare)) {
unset($result[$ip]);
break;
}
}
}
$result = array_keys($result);
file_put_contents('final.txt', implode($result));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment