ホームページ >バックエンド開発 >PHPチュートリアル >Discuz 5.0 における無害な IP データベースの読み取り機能の分析_PHP チュートリアル
Discuz 5.0 は独自の IP データを使用しなくなりましたが、Innocence IP データベースへのアクセスは少し面倒で、具体的な形式の分析については、次の 2 つのリンクを参照してください。他の言語では、記事の最後にあるリンクを参照してください。
「Innocence IP データベース形式の詳細な説明」
リンク 1: http://blog.csdn.net/heiyeshuwu/archive/2006/05/12/725675.aspx
リンク 2: http://lumaqq.linuxsir. org/article/qqwry_format_detail.html
Innocent IP データベース公式 Web サイト: http://www.cz88.net/ip/
Innocent IP データベースのダウンロード: http://update.cz88.net/soft/qqwry.rar
次の関数 conrvertip() は、Discuz!5_GBK/upload/include/misc.func.php パスにあります。興味がある場合は、詳細を読んで分析できます。(読みやすくするために以下のコードに簡単な変更を加えました。コアは変更されていません)
//=============== ======== ============
//
// 関数: 実アドレスを取得するための IP アドレス関数
// パラメータ: $ip - IP アドレス
// 作成者: [Discuz!] (C) Comsenz Inc .
//
//=============================== ===
function Convertip($ip) {
//IP データ ファイルのパス
$dat_path = 'QQWry.Dat'
//IP アドレスを確認する
if(!preg_match("/^d{1,3} .d{1,3}.d{1 ' rb')){
使用する 使用する一緒にアウト 一緒にアウト アウト アウト アウト アウト アウト アウトout of a through ‐ to rb') to {
” = $ip[0] * 16777216 + $ip[1] * 65536 + $ip[2] * 256 + $ip[3] //Get IP データインデックスの開始位置と終了位置
$DataBegin = fread($ fd, 4);
$ipbegin = implode('', unpack('L', $); DataBegin));
if($ipbegin < 0) $ipbegin += pow(2, 32);
if($ipend < ; 0) $ipend += pow(2, 32);
$ipend = ($ipbegin) / 7 + 1;
$EndNum = $ipAllNum;インデックス レコードから一致する IP レコードを検索するバイナリ検索メソッド
while($ip1num> $ipNum || $ip2num<$ipNum) {
$Middle= intval(($EndNum + $BeginNum) / 2); /ポインターをインデックス位置にオフセットし、4 バイトを読み取ります
fseek($fd, $ipbegin + 7 * $Middle);
$ipData1 = fread($fd, 4);
if(strlen($ipData1) < 4 ) {
fclose($fd);
return 'System Error';
// 抽出したデータを長整数に変換し、データが負の数の場合は 2 の 32 乗を加算します
0) $ IP1NUM+= POW (2, 32);
// 抽出の値は IP アドレスの値より大きく、終了位置は次のサイクルで変更されます
}
// 取得後。前のインデックス、インデックスを取得します
$ dataseek = FREAD ($ fd, 3);
if ($ dataseek) & lt; t Return 'システム エラー'
}
$ dataseek = Implode ('', unpack ('l', $ dataseek.chr (0));
Fseek ($ fd, $ dataseek); ipData2 = fread($fd, 4);
if(strlen($ipData2) < ; 4) {
fclose($fd);
'システム エラー' を返します }
$ip2num ($ip2num < $ipNum) {
$BeginNum $Middle 次のコードはわかりにくく、理解できません。興味のある方はゆっくり読んでみてください
$ipFlag = fread($fd, 1);
if($ipFlag == chr(1)) {
$ipSeek = fread($fd , 3);
if(strlen($ipSeek) < 3) {
fclose($fd);システム エラー';
$ipSeek = implode('' , unpack('L', $ipSeek .chr(0))); 3) fread($fd, 1); ($ipFlag == chr(2)) {
「システムエラー」を返します
{
de('', unpack(' L', $AddrSeek.chr(0)));
fseek($fd, $ AddrSeek);
while(($char = fread($fd, 1)) != chr(0))
$ipAddr1。 else {
fseek($fd, -1, SEEK_CUR);
while(($char = fread($fd, 1)) != chr(0))
$ipAddr1 .= $char;
$ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3);
if(strlen($AddrSeek2) < 3) {
fclose($fd);
「システムエラー」を返します。
}
$AddrSeek2 = implode('', unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($fd, -1, SEEK_CUR);
}
while(($char = fread($fd, 1)) != chr(0)){
$ipAddr2 .= $char;
}
}
fclose($fd);
//最後に相対的な代替操作を行った後に結果を返します
if(preg_match('/http/i', $ipAddr2)) {
$ipAddr2 = '';
}
$ipAddr = "$ipAddr1 $ipAddr2";
$ipaddr = preg_replace('/CZ88.NET/is', '', $ipaddr);
$ipaddr = preg_replace('/^s*/is', '', $ipaddr);
$ipaddr = preg_replace('/s*$/is', '', $ipaddr);
if(preg_match('/http/i', $ipaddr) || $ipaddr == '') {
$ipaddr = '不明';
}
$ipadr を返す;
}
//========================
//
// 调用举例(速度很快)
//
// ========================
echo convertip('219.238.235.10');
//输出: 北京市 電信通
echo convertip('23.56.82.12');
//输出:IANA
echo convertip('250.69.52.0');
//输出:IANA保留地址
echo convertip('238.69.52.0');
//出力:IANA 保留地址 多点転送用
echo convertip('192.168.0.1');
//出力:局域网对方和您在同一内部网
echo convertip('255.255.255.255');
//输出:纯真网络 2006年11月20日IPデータベース
?>