Habe es gefunden, danke. :) Ich poste mal nur noch mal meine letzte Version, da ich nicht glaube, dass ich ohne gegebenen Anlass noch was dran machen werde (sorry). Ich glaube, ich verstehe die eigentliche Problemstellung auch nicht so richtig, weil es nicht so sehr mein Bereich ist.
Vielleicht hilft es aber trotzdem irgendwem:
<?php
class Algo
{
private $masks;
private $maskKeys;
public function __construct(array $masks)
{
$this->masks = $this->rearrangeMasks($masks);
$this->maskKeys = array_keys($this->masks);
ksort($this->maskKeys);
}
private function rearrangeMasks(array $a)
{
$new = array();
foreach ($a as $item) {
list($ipv4, $cidr) = explode('/', $item);
$iplong = ip2long($ipv4);
$iplong >>= 32 - $cidr;
if (!isset($new[$cidr])) {
$new[$cidr] = array();
}
$new[$cidr][$iplong] = true;
}
return $new;
}
public function isMatch($ipv4)
{
$iplong = ip2long($ipv4);
foreach ($this->maskKeys as $i) {
if (isset($this->masks[$i][$iplong >> 32 - $i])) {
return true;
}
}
return false;
}
}
class AlgoTest extends PHPUnit_Framework_TestCase
{
private function ipFromBin($bin)
{
$parts = explode('.', $bin);
return implode('.', array_map('bindec', $parts));
}
private function maskFromBin($bin)
{
list($tmp, $cidr) = explode('/', $bin);
return $this->ipFromBin($tmp) . '/' . $cidr;
}
private function runAssertions(array $masks, array $assertions)
{
$algo = new Algo($masks);
foreach ($assertions as $assertion) {
list($ipv4, $expected) = $assertion;
$this->assertSame($expected, $algo->isMatch($ipv4), implode(', ', $masks) . ' : ' . $ipv4);
}
}
public function testMain()
{
$masks = array(
'192.168.11.12/24',
'62.10.11.12/32',
'128.10.11.12/8',
'96.50.51.52/16'
);
$assertions = array(
array('192.168.128.0', false),
array('192.168.11.255', true),
array('62.10.11.255', false),
array('62.10.11.12', true),
array('128.255.255.255', true),
array('129.255.255.255', false),
array('96.50.255.255', true),
array('97.50.51.52', false)
);
$this->runAssertions($masks, $assertions);
$masks = array(
$this->maskFromBin('11000000.10101000.00000001.10111100/27')
);
$assertions = array(
array($this->ipFromBin('11000000.10101000.00000001.10111111'), true),
array($this->ipFromBin('11000000.10101000.00000001.10100000'), true),
array($this->ipFromBin('11000000.10101000.00000001.10011111'), false),
array($this->ipFromBin('11000000.10101000.00000001.10000000'), false)
);
$this->runAssertions($masks, $assertions);
$masks = array(
$this->maskFromBin('11000000.10101000.00000001.10111100/1')
);
$assertions = array(
array($this->ipFromBin('11111111.11111111.11111111.11111111'), true),
array($this->ipFromBin('01000000.10101000.00000001.10011111'), false)
);
$this->runAssertions($masks, $assertions);
$masks = array(
$this->maskFromBin('11111111.11111111.11111111.11111111/32'),
$this->maskFromBin('00000000.00000000.00000000.00000000/32')
);
$assertions = array(
array($this->ipFromBin('11111111.11111111.11111111.11111111'), true),
array($this->ipFromBin('00000000.00000000.00000000.00000000'), true),
array($this->ipFromBin('11111111.11111111.11111111.11111110'), false),
array($this->ipFromBin('00000000.00000000.00000000.00000001'), false)
);
$this->runAssertions($masks, $assertions);
$masks = array(
$this->maskFromBin('11111111.11110000.00000000.00000000/12')
);
$assertions = array(
array($this->ipFromBin('11111111.11110000.11111111.11111111'), true),
array($this->ipFromBin('11111111.00001111.11111111.11111111'), false)
);
$this->runAssertions($masks, $assertions);
}
}