Posted on 2010-01-08 19:05
亂78糟 閱讀(7253)
評(píng)論(3) 編輯 收藏 引用 所屬分類(lèi):
C語(yǔ)言派系
首先聲明四點(diǎn):
- 本代碼是我在MFC中寫(xiě)的,用到了很多MFC種的類(lèi),如果要移植到其他開(kāi)發(fā)環(huán)境,請(qǐng)自行修改。
- 因?yàn)閷?shí)際具體要求,所有很多地方可能與大家使用的不同,原理代碼貼出來(lái),修改就簡(jiǎn)單了^_^。
- 本代碼僅僅是一個(gè)弱檢查,如果有大牛寫(xiě)出了C/C++的正則式判斷代碼,請(qǐng)一定要給我郵一份,感激涕零。
- 轉(zhuǎn)載請(qǐng)注明出處,也就是本隨筆地址啦。
原理:
URL是否合法的依據(jù)是RFC2369,可以
點(diǎn)擊這里查看RFC2369。
本段代碼的原理很簡(jiǎn)單,舉一個(gè)URL為例:
http://xxx.xxx.xx/ffd?=dd22,如何判斷是否合法?
如果你用過(guò)MFC中AfxParseUrl這個(gè)函數(shù),我相信你馬上就能明白90%,剩下的10%我后面再講,首先看下這個(gè)函數(shù)原型。
BOOL AFXAPI AfxParseURL(
LPCTSTR pstrURL,//待解析的URL,http://xxx.xxx.xx/ffd?=dd22
DWORD& dwServiceType,//解析出來(lái)的服務(wù)類(lèi)型,例如http,ftp之類(lèi)的,上面例子出來(lái)為1(AFX_INET_SERVICE_HTTP)
CString& strServer,//上面例子中的xxx.xxx.xx
CString& strObject,//上面例子中的/ffd?=dd22
INTERNET_PORT& nPort//端口
);
這個(gè)函數(shù)解析成功返回true,否則false。當(dāng)然,即便它返回true也不代表這個(gè)URL就是合法的,為什么呢?看這個(gè)例子:http://xxx/dd.html。所以重點(diǎn)變成了判斷
strServer這個(gè)參數(shù)是否合法,也就是我上面所說(shuō)的10%了。
服務(wù)器域名有很多子域名,例如asd.page1.cppblog.com、ddd.sina.com.cn。棄繁從簡(jiǎn),倒過(guò)來(lái),如果找到多個(gè).分開(kāi)的字段,并且最后一個(gè)域名是正確的,就是正確的URL格式。有個(gè)例外,那就是純IP,例如http://192.168.3.124/index.html。
OK,原理完了,上代碼。
代碼:
//校驗(yàn)URL是否合法文件路徑,依據(jù)為rfc2396
//這個(gè)函數(shù)只做粗略的校驗(yàn),不完全符合RFC2369
//僅支持IPV4
BOOL CAddDlg::CheckURL(const CString &szUrl, CString &szMsg)
{
DWORD dwService = 0;
DWORD dwValid = AFX_INET_SERVICE_FTP|AFX_INET_SERVICE_HTTP|AFX_INET_SERVICE_HTTPS|AFX_INET_SERVICE_FILE;
CString strServer;
CString strObject;
INTERNET_PORT port;
BOOL bValid = AfxParseURL(szUrl, dwService, strServer, strObject, port);
if ( !bValid || strObject.IsEmpty() || strObject == "/" || strServer == "localhost"
)
{
szMsg = szUrl + " \n不是一個(gè)合法的下載地址URL";
return FALSE;
}
else//開(kāi)始檢驗(yàn)解析出來(lái)的部分
{
if ( (dwService & dwValid) == 0 )
{
szMsg = szUrl + "\n不支持的服務(wù)類(lèi)型,目前僅支持http,https,ftp,file";
return FALSE;
}
if ( (dwService & AFX_INET_SERVICE_FILE) != 0 )//file協(xié)議直接返回TRUE
{
return TRUE;
}
CStringArray arr;
CString dom;
int i, size = 0;
ExtractString(arr, strServer, ".");
size = arr.GetCount();
if ( size == 0 )
return TRUE;
dom = arr.GetAt( size-1 );
for ( i = 0; i < size; i++)
{
if ( IsGb2312(arr.GetAt(i)) )
{
szMsg = szUrl + " \n不支持包含中文的域名";
return FALSE;
}
}
//先看下是不是192.168.3.2這種IP形式的地址
if ( IsNumber(dom) )
{
bool bt = true;
if ( size == 4 )
{
for ( i = 0; i < size; i++ )
{
UINT32 num = CString2UINT32(dom);
if (num < 0 && num > 255)
{
bt = false;
continue;
}
}
if ( bt )
return TRUE;
}
}
else if (size > 1)//查一下域名表
{
for (i = 0; i < DOMAIN_NUM; i++)
{
if (dom == szDomainTable[i])
return TRUE;
}
}
szMsg = szUrl + " \n不是一個(gè)合法的下載地址URL";
return FALSE;
}
return TRUE;
}
上面代碼中用到的幾個(gè)函數(shù)如
ExtractString、IsGb2312都很簡(jiǎn)單,為不增加代碼長(zhǎng)度影響閱讀,故不再貼出。szDomainTable是我定義的一個(gè)域名數(shù)組,可以
點(diǎn)擊這里下載domain.h。
PS:
本來(lái)想找個(gè)現(xiàn)成的,可網(wǎng)上搜了好長(zhǎng)時(shí)間,無(wú)果。后來(lái)一大牛給我發(fā)了個(gè)JAVA的正則式判斷代碼,

,不懂JAVA的c++er飄過(guò)~~~~~