UN AUTRE POINT DE VUE
Bonjour. Vous pouvez vérifier si une adresse est bloqué ou pas, via l'accès à deux octets dans deux morceaux de données chaque 8 KO de long. Oui, je suis sérieux... s'il vous Plaît être patient car il faut un peu long à expliquer.
LA THÉORIE
Une adresse IP est une adresse, en fait un 4 nombre d'octet.
La question est, que si nous la faire à l'adresse de positions de bits?.
La réponse: eh Bien ok, nous allons avoir
2^32 = 4 Giga Bits
de l'espace d'adressage et qui va prendre
4Gb/8 = 512 Mega Bytes
de l'allocation. Ouch! Mais ne vous inquiétez pas, nous n'allons pas bloquer tout le ipverse et 512 mo est une exagération.
Cela peut nous ouvrir un chemin vers la solution.
Le Lilliputien Cas
Pensez à un Lilliputien monde, il existe seulement des adresses ip de 0 à 65535. Si les adresses sont comme de 0,1 ou de 42.42 jusqu'à 255.255.
Maintenant, le Roi de ce monde veut bloquer plusieurs L-IP (lilliput ip).
D'abord, il construit un virtuel 2D bit map qui est de 256 * 256 bits qui prend :
64 K Bits = 8 K Bytes.
Il décide de bloc méchant "révolution" du site ce qu'il déteste parce qu'il est le roi, l'adresse est 56.28, par exemple.
Address = (56 * 256) + 28 = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) = 1795.
Bit position= 14364 % 8 = 4.(modulus)
Il ouvre le fichier map, accède à 1795th octet et définit le bit 4 (|16), puis de l'écrit à marquer le site comme bloqué.
Lors de son scénario voit le 56.28, il fait le même calcul et regarde le peu, et si elle est définie, les blocs de l'adresse.
Maintenant, quelle est la morale de l'histoire? Eh bien, nous pouvons utiliser ce lilliputien de la structure.
LA PRATIQUE
Le Monde Réel De Cas
Nous pouvons appliquer le Lilliputien de cas du monde réel, avec une "utiliser quand vous en avez besoin" approche puisque l'allocation d'une 512 mo de fichier n'est pas un bon choix.
Pensez à une table de base de données nommé BLOCS avec des entrées comme:
IpHead(key): unsigned 16 bit integer,
Map : 8KB BLOB(fixed size),
EntryCount : unsigned 16 bit integer.
Et une autre table avec une seule entrée à la structure ci-dessous nommée BASE
Map : 8KB BLOB(fixed size).
Maintenant, disons que vous avez une entrée d'adresse 56.28.10.2
Script accède à la BASE de la table et obtient la Carte.
Il regarde le supérieur de l'ordre des numéros IP 56.28:
Address = (56 * 256) + 28 = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) = 1795.
Bit position= 14364 % 8 = 4.(modulus)
Regarde octet 1795 bits 4 à la Carte.
Si le bit n'est pas défini, aucune autre opération n'est nécessaire, et donc il n'y a pas d'adresse ip bloquée dans la gamme 56.28.0.0 - 56.28.255.255 .
Si le bit est défini, alors le script accède à la table des BLOCS.
Le supérieur de l'ordre des numéros IP ont été 56.28 qui donne 14364 ainsi, le script de requêtes de la table des BLOCS avec index IpHead = 14364. Extrait de l'enregistrement. L'enregistrement doit exister car elle est marquée à la BASE.
Le Script fait le calcul pour un ordre inférieur de l'adresse IP
Address = (10 * 256) + 2 = 2562.(bit position in whole map)
Byte in map = floor(2562 / 8) = 320.
Bit position= 2562 % 8 = 2.(modulus)
Puis il vérifie si l'adresse est bloquée en regardant les 2 bits de l'octet 320 de la Carte du champ.
Travail de fait!
Q1: Pourquoi utilisons-nous de BASE à tous, nous avons pu interroger directement les BLOCS avec 14364.
A1: Oui, on pourrait, mais à la carte de BASE de recherche sera plus rapide, puis BTREE la recherche de tout serveur de base de données.
Q2: Quelle est la EntryCount champ dans la table des BLOCS?
A2: C'est le nombre d'adresses ip bloquées dans la carte de terrain dans le même dossier.
Donc, si nous débloquer l'ip et EntryCount atteint 0 qui BLOQUE disque devient
inutiles. Il peut être effacé et le bit correspondant sur la BASE de la carte sera annulée.
À mon humble avis, cette approche sera aussi rapide que l'éclair. Aussi pour le blob de l'allocation de 8K par enregistrement. Depuis db serveurs de garder les gouttes de séparer les fichiers, les systèmes de fichiers 4K, 8K ou des multiples de 4K pagination va réagir vite.
Dans le cas des adresses bloquées sont trop dispersées
Eh bien, c'est un sujet de préoccupation, ce qui fera de la base de données de la table des BLOCS pour augmenter inutilement.
Mais pour de tels cas, l'alternative est d'utiliser un 256*256*256 peu de cube qui est de 16777216 bits, égalant à 2097152 octets = 2 MO.
Pour notre exemple précédent Ip Plus grande résolution est :
(56 * 65536)+(28 * 256)+10
Donc de BASE deviendra un fichier de 2 mo au lieu d'un db enregistrement de la table, qui sera ouvert (fopen, etc.) et peu seront abordées par la recherche (comme fseek, ne jamais lire le contenu du fichier, inutile) puis accéder à la table des BLOCS avec la structure ci-dessous:
IpHead(key): unsigned 32 bit integer, (only 24 bit is used)
Map : 32 unsigned 8 bit integers(char maybe),(256 bit fixed)
EntryCount : unsigned 8 bit integer.
Voici l'exemple de code php pour bloquer la vérification de bitplane-bitplane (8K 8K) version:
Remarque: Ce script peut être optimisé via l'élimination de plusieurs appels, etc..
Mais écrit comme ça pour garder facile à comprendre.
<?
define('BLOCK_ON_ERROR', true); // WARNING if true errors block everyone
$shost = 'hosturl';
$suser = 'username';
$spass = 'password';
$sdbip = 'database';
$slink = null;
$slink = mysqli_connect($shost, $suser, $spass, $sdbip);
if (! $slink) {
$blocked = BLOCK_ON_ERROR;
} else {
$blocked = isBlocked();
mysqli_close($slink); // clean, tidy...
}
if ($blocked) {
// do what ever you want when blocked
} else {
// do what ever you want when not blocked
}
exit(0);
function getUserIp() {
$st = array(
'HTTP_CLIENT_IP',
'REMOTE_ADDR',
'HTTP_X_FORWARDED_FOR'
);
foreach ( $st as $v )
if (! empty($_SERVER[$v]))
return ($_SERVER[$v]);
return ("");
}
function ipToArray($ip) {
$ip = explode('.', $ip);
foreach ( $ip as $k => $v )
$ip[$k] = intval($v);
return ($ip);
}
function calculateBitPos($IpH, $IpL) {
$BitAdr = ($IpH * 256) + $IpL;
$BytAdr = floor($BitAdr / 8);
$BitOfs = $BitAdr % 8;
$BitMask = 1;
$BitMask = $BitMask << $BitOfs;
return (array(
'bytePos' => $BytAdr,
'bitMask' => $BitMask
));
}
function getBaseMap($link) {
$q = 'SELECT * FROM BASE WHERE id = 0';
$r = mysqli_query($link, $q);
if (! $r)
return (null);
$m = mysqli_fetch_assoc($r);
mysqli_free_result($r);
return ($m['map']);
}
function getBlocksMap($link, $IpHead) {
$q = "SELECT * FROM BLOCKS WHERE IpHead = $IpHead";
$r = mysqli_query($link, $q);
if (! $r)
return (null);
$m = mysqli_fetch_assoc($r);
mysqli_free_result($r);
return ($m['map']);
}
function isBlocked() {
global $slink;
$ip = getUserIp();
if($ip == "")
return (BLOCK_ON_ERROR);
$ip = ipToArray($ip);
// here you can embed preliminary checks like ip[0] = 10 exit(0)
// for unblocking or blocking address range 10 or 192 or 127 etc....
// Look at base table base record.
// map is a php string, which in fact is a good byte array
$map = getBaseMap($slink);
if (! $map)
return (BLOCK_ON_ERROR);
$p = calculateBitPos($ip[0], $ip[1]);
$c = ord($map[$p['bytePos']]);
if (($c & $p['bitMask']) == 0)
return (false); // No address blocked
// Look at blocks table related record
$map = getBlocksMap($slink, $p[0]);
if (! $map)
return (BLOCK_ON_ERROR);
$p = calculateBitPos($ip[2], $ip[3]);
$c = ord($map[$p['bytePos']]);
return (($c & $p['bitMask']) != 0);
}
?>
J'espère que cette aide.
Si vous avez des questions sur les détails, je serai heureux de répondre.