Viszont közben néztem a readme-jüket és mivel nem vágtam, hogy mi az a CIDR notation és mit takar a perjel mögötti rész és a net meg nem adott gyors, egymondatos választ, hogy az a tartomány komplementer bitszáma (azaz vond ki 32-ből és annyi bitnyi a tartomány, csak maszkolj is), így inkább kerestem pöhöpöben konverterfüggvényt és ezt találtam:function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}Na, mondom, ez jó bonyolultra sikeredett; egyszerűsítsük ki és akkor tán még meg is értem, hogy mi a lófasz van ideírva. Nulladik lépés gyanánt dobáljuk ki az összes felesleges dupla zárójelet, hogy ne zavarjanak feleslegesen be:function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip(ip2long($cidr[0]) & (-1 << (32 - (int)$cidr[1])));
$range[1] = long2ip(ip2long($range[0]) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}Első lépésben meg a tömbnek az előre deklarálását és utána a menetközbeni beírkálást küldjük a levesbe:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$begin = long2ip(ip2long($cidr[0]) & (-1 << (32 - (int)$cidr[1])));
$end = long2ip(ip2long($begin) + pow(2, (32 - (int)$cidr[1])) - 1);
return array($begin, $end);
}Aztán, mivel ez a menetközbeni ip2long() -> long2ip() -> ip2long() -> long2ip() oda-vissza konvertálás teljesen felesleges, így talán ezt is mellőzzük; elég az elején, majd a végén:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$begin = ip2long($cidr[0]) & (-1 << (32 - (int)$cidr[1]));
$end = $begin + pow(2, (32 - (int)$cidr[1])) - 1;
return array(long2ip($begin), long2ip($end));
}Aztán, a (32 - (int)$cidr[1]) kétszer szerepel, szóval pakoljuk már ki egy változóba:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$bits = 32 - (int)$cidr[1];
$begin = ip2long($cidr[0]) & (-1 << $bits);
$end = $begin + pow(2, $bits) - 1;
return array(long2ip($begin), long2ip($end));
}Az a pow(2, $bits) nagyon csúnya, azt simán fel lehet írni úgy, hogy 1 << $bits:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$bits = 32 - (int)$cidr[1];
$begin = ip2long($cidr[0]) & (-1 << $bits);
$end = $begin + (1 << $bits) - 1;
return array(long2ip($begin), long2ip($end));
}Itt felfigyel az ember arra, hogy a -1 << $bits az tkp. $bits db. nullát shiftel be egy csupa egyesből álló változóba, míg az (1 << $bits) - 1 az ennek az inverzét csinálja: $bits db. egyest shiftel be egy csupa nullából álló változóba. Akkor ezt fel lehet venni egy maszkváltozóba és az egyik helyen a normál, a másik helyen az inverz verziót használni:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$bits = 32 - (int)$cidr[1];
$mask = (1 << $bits) - 1;
$begin = ip2long($cidr[0]) & ~$mask;
$end = $begin + $mask;
return array(long2ip($begin), long2ip($end));
}A $bits ezen a ponton többé már nem szükséges, mert csak egyszer van használva, szóval leves. És az $end-re is ugyanez vonatkozik. (Oké, az egész végig így volt, de az az átláthatóság miatt volt így.) Uccsó verzió:function cidrToRange($cidr) {
$cidr = explode('/', $cidr);
$mask = (1 << (32 - (int)$cidr[1])) - 1;
$begin = ip2long($cidr[0]) & ~$mask;
return array(long2ip($begin), long2ip($begin + $mask));
}Azért így sokkal érthetőbb. Olyannyira, hogy még nekem is leesett a fenti. :P Szóval köszi jonavonnak, amiért "elmagyarázta", hehe. (Egyébként nálunk a végső long2ip nem is lesz használva, hiszen mi a túróért konvertálgassam folyton oda-vissza, ha úgyis tartományokat fogunk használni és a DB-ben is két szám lesz, nem két IP cím.) |