ホームページ  >  記事  >  php教程  >  Discuz 5.0における無害なIPデータベースの読み取り機能の分析

Discuz 5.0における無害なIPデータベースの読み取り機能の分析

WBOY
WBOYオリジナル
2016-06-13 12:32:30932ブラウズ

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,3}.d{1,3 }$/", $ip)) {<> Return 'IP Address Error';
}
// IP データ ファイルを開きます
if (! $ Fd = @fopen ($ dat_path, 'rb ')) {
RETURN ' IP 日付ファイルが存在しないか、アクセスが拒否されました';
}

// 操作用に IP を分解し、整数を取得します
$ip =explode(' .', $ip);
$ipNum = $ip[0] * 16777216 $ip[1] * 65536 $ip[2] * 256 $ip[3]; // を取得します。 IP データインデックスの開始位置と終了位置
$DataBegin = fread($fd, 4);
$DataEnd = fread($fd, 4);
$ipbegin = implode('', unpack('L) ', $DataBegin));
if ($ipbegin < 0) $ipbegin = pow(2, 32)
$ipend = implode('', unpack('L', $DataEnd));
if($ipend < 0) $ipend = pow(2, 32);
$ipAllNum = ($ipend - $ipbegin) / 7 1;

$BeginNum = 0; 🎜> $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);
'システム エラー'; }
//データを長整数に変換します。データが負の場合は、2の32乗を加算します。
$ip1num = implode('', unpack('L', $ipData1) );
if($ip1num < 0) $ip1num = pow(2, 32);

//抽出された長整数が IP アドレスより大きい場合は、次の整数の終了位置を変更しますcycle
if($ip1num > $ipNum) {
$EndNum = $Middle;
continue;
}

// 前のインデックスを取得した後、次のインデックスを取得します
$DataSeek = fread($fd, 3);
if(strlen($DataSeek)
return 'システム エラー'; DataSeek = implode('', unpack(' L', $DataSeek.chr(0)));
fseek($fd, $DataSeek);
$ipData2 = fread($fd, 4); 🎜> if(strlen($ipData2) < ; 4) {

$ip2num = implode('', unpack('L', $ipData2));
if($ip2num < 0) $ip2num = pow(2, 32); / 見つからないプロンプト不明
if($ip2num < $ipNum) {
if($Middle == $BeginNum) {
return ' 不明'; >}
$ Beginnum = $ MIDDLE;
}
}

// 以下のコードはめまぐるしく読みます、読まないでください、ゆっくり読んでください
$ ipflag = fread($fd , 1);
if($ipFlag == chr(1)) {
$ipSeek = fread($fd, 3);
if(strlen($ipSeek) fclose($fd);
return 'システム エラー';
}
$ipSeek = implode('', unpack('L', $ipSeek.chr(0))) ; fseek($fd, $ipSeek);
$ipFlag = fread($fd, 1);
}

if($ipFlag == chr(2)) {
$AddrSeek = fread($fd, 3);
if(strlen($AddrSeek)
fclose($fd);
return 'システム エラー'; ipFlag = fread($fd, 1);
if($ipFlag == chr(2)) {
$AddrSeek2 = fread($fd, 3)
if(strlen( $AddrSeek2) < ; 3) {
unpack('L', $AddrSeek2.chr(0)));
fseek($fd, $AddrSeek2);
} else {
fseek($ fd, -1, SEEK_CUR);
}

while (($char = fread($fd, 1)) != chr(0))
$ipAddr2 .= $char; 🎜>
$AddrSeek = implode('', unpack('L', $AddrSeek.chr(0)));
fseek($fd, $AddrSeek); while(( $char = fread($fd, 1)) != chr(0))
$ipAddr1 .= $char;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); (strlen($AddrSeek2) < 3) {
unpack('L', 2.chr(0)));
fseek($fd, $AddrSeek2); } else { 🎜> while (($char = fread($fd, 1)) != chr(0)){
$ipAddr2 .= $char; >
//最後に対応する置換操作を実行し、結果を返します
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 = '不明' }

return $ipaddr;


//== =========== ==========
//
// 呼び出し例 (非常に高速)
//
//= ============= ==========

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')
//出力: LAN 相手は自分と同じイントラネット内にあります

echo Convertip('255.255.255.255');
//出力: 2006 年 11 月 20 日の Innocence Network IP データ

?>

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。