2007年11月9日 星期五

PHP源碼-利用 QQWry.Dat 實現 IP 地址高效檢索

根據 LumaQQ 開發者文檔中的純真 IP 數據庫格式詳解,我編寫了一個 PHP 的查詢 IP 所在地區信息的類。在編寫過程中發現純真 IP 數據庫格式詳解中關於記錄區的描述不是很全面,不過出入也不是很大,所以我沒必要再寫一份純真 IP 數據庫的格式說明了,大家感興趣的話,讀一讀下面的代碼應該就能看出來了。代碼中加了很詳細的註釋,應該很容易讀懂的。

在創建這個類的一個實例後,實例中就保存了打開的文件指針和一些查詢需要的信息,每次查詢時不需要重新打開文件,直到頁面執行結束後,打開的文件才會自動關閉。這樣。在一個頁面內進行多次查詢時,效率是很高的。並且此類不僅可以直接查詢 IP,還可以自動將域名解析為 IP 進行查詢。

下面是程序代碼:


--------------------------------------------------------------------------------

/**
* IP 地理位置查詢類
*
* @author 馬秉堯
* @version 1.5
* @copyright 2005 CoolCode.CN
*/
class IpLocation {
/**
* QQWry.Dat文件指針
*
* @var resource
*/
var $fp;

/**
* 第一條IP記錄的偏移地址
*
* @var int
*/
var $firstip;

/**
* 最後一條IP記錄的偏移地址
*
* @var int
*/
var $lastip;

/**
* IP記錄的總條數(不包含版本信息記錄)
*
* @var int
*/
var $totalip;

/**
* 返回讀取的長整型數
*
* @access private
* @return int
*/
function getlong() {
//將讀取的little-endian編碼的4個字節轉化為長整型數
$result = unpack('Vlong', fread($this->fp, 4));
return $result['long'];
}

/**
* 返回讀取的3個字節的長整型數
*
* @access private
* @return int
*/
function getlong3() {
//將讀取的little-endian編碼的3個字節轉化為長整型數
$result = unpack('Vlong', fread($this->fp, 3).chr(0));
return $result['long'];
}

/**
* 返回壓縮後可進行比較的IP地址
*
* @access private
* @param string $ip
* @return string
*/
function packip($ip) {
// 將IP地址轉化為長整型數,如果在PHP5中,IP地址錯誤,則返回False,
// 這時intval將Flase轉化為整數-1,之後壓縮成big-endian編碼的字符串
return pack('N', intval(ip2long($ip)));
}

/**
* 返回讀取的字符串
*
* @access private
* @param string $data
* @return string
*/
function getstring($data = "") {
$char = fread($this->fp, 1);
while (ord($char) > 0) { // 字符串按照C格式保存,以\0結束
$data .= $char; // 將讀取的字符連接到給定字符串之後
$char = fread($this->fp, 1);
}
return $data;
}

/**
* 返回地區信息
*
* @access private
* @return string
*/
function getarea() {
$byte = fread($this->fp, 1); // 標誌字節
switch (ord($byte)) {
case 0: // 沒有區域信息
$area = "";
break;
case 1:
case 2: // 標誌字節為1或2,表示區域信息被重定向
fseek($this->fp, $this->getlong3());
$area = $this->getstring();
break;
default: // 否則,表示區域信息沒有被重定向
$area = $this->getstring($byte);
break;
}
return $area;
}

/**
* 根據所給 IP 地址或域名返回所在地區信息
*
* @access public
* @param string $ip
* @return array
*/
function getlocation($ip) {
if (!$this->fp) return null; // 如果數據文件沒有被正確打開,則直接返回空
$location['ip'] = gethostbyname($ip); // 將輸入的域名轉化為IP地址
$ip = $this->packip($location['ip']); // 將輸入的IP地址轉化為可比較的IP地址
// 不合法的IP地址會被轉化為255.255.255.255
// 對分搜索
$l = 0; // 搜索的下邊界
$u = $this->totalip; // 搜索的上邊界
$findip = $this->lastip; // 如果沒有找到就返回最後一條IP記錄(QQWry.Dat的版本信息)
while ($l <= $u) { // 當上邊界小於下邊界時,查找失敗
$i = floor(($l + $u) / 2); // 計算近似中間記錄
fseek($this->fp, $this->firstip + $i * 7);
$beginip = strrev(fread($this->fp, 4)); // 獲取中間記錄的開始IP地址
// strrev函數在這裡的作用是將little-endian的壓縮IP地址轉化為big-endian的格式
// 以便用於比較,後面相同。
if ($ip < $beginip) { // 用戶的IP小於中間記錄的開始IP地址時
$u = $i - 1; // 將搜索的上邊界修改為中間記錄減一
}
else {
fseek($this->fp, $this->getlong3());
$endip = strrev(fread($this->fp, 4)); // 獲取中間記錄的結束IP地址
if ($ip > $endip) { // 用戶的IP大於中間記錄的結束IP地址時
$l = $i + 1; // 將搜索的下邊界修改為中間記錄加一
}
else { // 用戶的IP在中間記錄的IP範圍內時
$findip = $this->firstip + $i * 7;
break; // 則表示找到結果,退出循環
}
}
}

//獲取查找到的IP地理位置信息
fseek($this->fp, $findip);
$location['beginip'] = long2ip($this->getlong()); // 用戶IP所在範圍的開始地址
$offset = $this->getlong3();
fseek($this->fp, $offset);
$location['endip'] = long2ip($this->getlong()); // 用戶IP所在範圍的結束地址
$byte = fread($this->fp, 1); // 標誌字節
switch (ord($byte)) {
case 1: // 標誌字節為1,表示國家和區域信息都被同時重定向
$countryOffset = $this->getlong3(); // 重定向地址
fseek($this->fp, $countryOffset);
$byte = fread($this->fp, 1); // 標誌字節
switch (ord($byte)) {
case 2: // 標誌字節為2,表示國家信息又被重定向
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $countryOffset + 4);
$location['area'] = $this->getarea();
break;
default: // 否則,表示國家信息沒有被重定向
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
break;
case 2: // 標誌字節為2,表示國家信息被重定向
fseek($this->fp, $this->getlong3());
$location['country'] = $this->getstring();
fseek($this->fp, $offset + 8);
$location['area'] = $this->getarea();
break;
default: // 否則,表示國家信息沒有被重定向
$location['country'] = $this->getstring($byte);
$location['area'] = $this->getarea();
break;
}
if ($location['country'] == " CZ88.NET") { // CZ88.NET表示沒有有效信息
$location['country'] = "未知";
}
if ($location['area'] == " CZ88.NET") {
$location['area'] = "";
}
return $location;
}

/**
* 構造函數,打開 QQWry.Dat 文件並初始化類中的信息
*
* @param string $filename
* @return IpLocation
*/
function IpLocation($filename = "QQWry.Dat") {
if (($this->fp = @fopen($filename, 'rb')) !== false) {
$this->firstip = $this->getlong();
$this->lastip = $this->getlong();
$this->totalip = ($this->lastip - $this->firstip) / 7;
//註冊析構函數,使其在程序執行結束時執行
register_shutdown_function(array(&$this, '_IpLocation'));
}
}

/**
* 析構函數,用於在頁面執行結束後自動關閉打開的文件。
*
*/
function _IpLocation() {
fclose($this->fp);
}
}
?>

讀取漢字點陣數據

/**
* 讀取漢字點陣數據
*
* @author legend
* @link http://www.ugia.cn/?p=82
* @Copyright www.ugia.cn
*/

$str = "中華人民共和國";

$font_file_name = "mingliu12.fon"; // 點陣字庫文件名
$font_width = 12; // 單字寬度
$font_height = 12; // 單字高度
$start_offset = 0; // 偏移

$fp = fopen($font_file_name, "rb");

$offset_size = $font_width * $font_height / 8;
$string_size = $font_width * $font_height;
$dot_string = "";

for ($i = 0; $i < strlen($str); $i ++)
{
if (ord($str{$i}) > 160)
{
// 先求區位碼,然後再計算其在區位碼二維表中的位置,進而得出此字符在文件中的偏移
$offset = ((ord($str{$i}) - 0xa1) * 94 + ord($str{$i + 1}) - 0xa1) * $offset_size;
$i ++;
}
else
{
$offset = (ord($str{$i}) + 156 - 1) * $offset_size;
}

// 讀取其點陣數據
fseek($fp, $start_offset + $offset, SEEK_SET);
$bindot = fread($fp, $offset_size);

for ($j = 0; $j < $offset_size; $j ++)
{
// 將二進制點陣數據轉化為字符串
$dot_string .= sprintf("%08b", ord($bindot{$j}));
}
}

fclose($fp);

echo $dot_string;
?>

免費防毒軟件介紹及下載

Avast! 4 Home(有中文版)http://www.avast.com/eng/download-avast-home.html
功能強大的掃毒除毒防間諜軟體,可以掃瞄多種檔案,支援多國語言(含繁簡中英文),具實時監察及自動更新功能,能用於各MS Window上,限個人家用及非商業使用,付費版會提供進階功能。

Avira AntiVir 7.0(傳聞比卡巴斯基更強)http://www.free-av.com/antivirus/allinonen.html
功能不錯的掃毒除毒軟體,可用於Window、Linux、BSD及Solaris,具實時監察及自動更新功能,但只有付費版本才提供比較完善的防間諜軟體功能,限個人非商業使用。

AOL Active Virus Shield(免費版卡巴斯基)http://www.activevirusshield.com/antivirus/freeav/index.adp?
功能強大的掃毒除毒防間諜軟體,具實時監察及自動更新功能, 能用於各MS Window上,任何人皆可免費使用,需要輸入自己的電郵以取得啟動碼。

AVG Anti-Virus Free & AVG Anti-Spyware Free 7.5
http://free.grisoft.com/doc/2/lng/us/tpl/v5
功能強大的掃毒除毒防間諜軟體,可用於Window及Linux,具實時監察功能,限非商業使用。此外這家公司又出了ewido anti-spyware Free,可以用來掃間諜軟體,但卻不具實時監察功能及自動更新功能,可用於Window2000/XP,限非商業使用。

Comodo AntiVirus 1.1 beta
http://www.antivirus.comodo.com/overview.html?currency=USDRion=Asia%20%26%20Pacific&country=HK
功能強大的掃毒除毒防間諜軟體,具實時監察及自動更新功能,能用於MS window xp(sp2)、window 2000(sp4)或以上的系統(不能用於98/me),無任何個人商用的使用限制。

BitDefender 8 Free Edition(收費版防毒能力2006年世界第一)
http://www.bitdefender.com/PRODUCT-14-en--BitDefender-8-Free-Edition.html
功能強大的掃毒除毒防間諜軟體,個人認為它的掃毒功能比上述三個都要強一點,具自動更新功能,可是只有付費版才有實時監察功能(只好裝了上述一個軟體之後再安這個), 可用於Window及Linux。(看不到有任何用途限制)

a-squared Free & a-squared HiJackFree
http://www.emsisoft.com/en/software/free/
功能不錯的掃毒除毒防間諜軟體,可是只有付費版才有實時監察功能及自動更新功能,該公司也推出了a-squared HiJackFree,一個為對電腦系統有探入認識的專業家而設,提供調節系統,控制及移除間諜軟體等功能,以上兩者能用於各MS Window上,但只限於個人使用。

ClamWin Free Antivirus
http://www.clamwin.com/content/view/18/46/
功能強大的掃毒除毒防間諜軟體,能用於各MS Window上,具自動更新功能,但卻沒有實時監察病毒間諜軟體的安全功能,它是開發自ClamAV,同樣是掃毒除毒防間諜軟體(用於Linux/BSD/UNIX-like OSes)。

CA Internet Security Suite 2007
http://home3.ca.com/Microsoft/Default.aspx?sc_lang=en-US
可試用整整一年。須再官方網頁註冊,以EMAIL換取一個試用序號,會不會寄垃圾信?不知道,還沒收過。

Norton AntiVirus 2005 Special Edition - 防毒公用程式
http://pack.google.com/intl/zh-tw/installer_eula.html?cinst=on&ci_symantec=on
這是Google軟體集裡面的其中一個免費坊毒軟體,雖然是舊版,還勉強可用,還信得過諾頓的,可以試試看。此軟體可免費使用6個月。

Windows Defender(微軟官方出品)http://www.microsoft.com/taiwan/athome/security/spyware/software/default.mspx
Windows Defender (Beta 2) 是一個免費的程式,可協助您的電腦避免由間諜軟體及其他有害軟體所帶來的快顯視窗、效能低落及安全性威脅等侵擾。 Windows Defender (Beta 2) 目前僅提供英文版、德文版及日文版,在 Beta 版之後將會陸續提供其他語言版本。

F-Secure Anti-Vires 2007
http://www.f-secure.com
這是來自於Kaspersky的緝毒引擎,F-Secure主要是以KAV的引擎為主其它引擎為輔,軟體在官網有在送正式版序號。

VCatch
http://www.vcatch.com/download.html
VCatch同樣也是一個全面完整功能的防毒軟件,可惜的是,VCatch本身是帶有adware的,安裝了它不時會彈出廣告。

SpyDefense
http://www.everestlabs.com/antispyware-download/
SpyDefense 是一個免費的反間,反惡意木馬軟件。

SpywareGuard 2.2
http://www.javacoolsoftware.com/spywareguard.html
SpywareGuard提供即時的反間保護,可配合SpywareBlaster使用。

SpywareBlaster 3.5.1
http://www.javacoolsoftware.com/spywareblaster.html
SpywareBlaster可以在你瀏覽網頁時,防止不良網站在你的電腦內安裝不良的程式。而這個軟件跟其他的不同,就是只針對網頁,而且不會在關閉後仍在背後運行省下記憶體。

Spybot - Search & Destroy(有中文版)http://www.spybot.com/ct/download/index.html
掃瞄並清除間諜程式、廣告軟體、劫持作業系統設定的元件,與其他惡意的軟體。

PC Tools AntiVirus 3.1 Free Edition
http://www.pctools.com/free-antivirus/
PC Tools AntiVirus是PCTools公司出品的一款可以防殺計算機病毒的計算機防衛工具軟件。為個人電腦提供世界一流的保護,利用快速更新和OnGuard技術攔截網絡病毒,蠕蟲和特洛伊。

360 安全衛士
http://360safe.com/
與卡巴斯基攜手打造病毒查殺模組,用戶在使用360安全衛士同時即可免費使用最新版卡巴斯基反病毒軟體。

PHP中在字符串中查找某個字符

PHP中查找字符有substr()和strstr兩個函數來處理,我沒事情自己想寫個簡單的算法,能夠從一個字符串中找出一個字符是否存在.

代碼如下:

$str = "aaa";
$substr = "a";

function check_str($str, $substr)
{
for ( $i=0; $i {
if ($substr == $str[$i])
{
return true;
}
else
{
return false;
}
}
}
?>

算法簡單,不能保證沒錯誤,只是娛樂....

令 BT 和 eD2k 達到最快下載速度

Windows XP 有開防火牆的才需要看

照以下步驟設定即可(不用重新開機,馬上就有效用)
1. 控制台
2. 網路連線 > 寬頻連線 及 區域連線
3. 內容
4. 進階
5. 設定 > 服務 > 新增
6. 服務描述 輸入 如 BT-6881,電腦名稱輸入 localhost
「 內部連接埠號碼 」與「 外部連接埠號碼 」設為目前 BT 和 eD2k 正在使用的連接埠( Port ) 如 6881
「 BT 沒變更過的話是 6881 - 6889 」
「 eD2k 沒變更過的話是 4662 」
7. 選 TCP
8. 完成按 [確定]
9. 最後!將這新增的服務勾選起來

隱藏副檔名

第一步 :

建立 : .hatccess 檔


第二步 抄下這二個指令

RewriteEngine on
RewriteRule ^twbb$ index.php $T=application/x-httpd-php]
第三步 丟到目前正在執行的目錄

檢查字串為繁體的函數

function isBig5($c="")
{
//is_big5
if($c=="")return false; //空字串
$len_of_c=strlen($c);

if($len_of_c%2==1)return false; //長度非偶數
for($ii=0;$ii<$len_of_c;$ii+=2){
$chk_c=substr($c,$ii,2);
$bc = hexdec(bin2hex($chk_c));
if(($bc>=0xa440 && $bc<= 0xc67e) || ($bc>=0xc940 && $bc<= 0xf9fe) || ($bc>=0xa140 && $bc<= 0xa3fe) ||
($bc>=0xc6a1 && $bc<= 0xc8fe))$nothing=true;
else return false;
}

return true;

}
?>