【演算法】ASP快速判斷IP是電信OR網通

來源:互聯網
上載者:User

  判斷IP的來源是電信還是網通,常用於網站的背景程式.典型的做法當然是查詢資料庫,資料庫裡儲存著網通(或電信)的IP範圍,然後通過範圍搜尋來決定該IP是否在網通(或電信)的區間內.不過每次都得查詢資料庫,效率顯然很低.

   

  不多廢話,直接開始說一種超快的演算法吧.既然要極快,莫過於o(1)的複雜度,所以開闢一巨大的緩衝區,用經典的空間換時間,通過查表一步即可判定.那如何定義表的大小,還有key?先從CNC.txt這個檔案看起.
(http://www.etherdream.com/FunnyScript/IPRange/CNC.txt)

   

      這個檔案是中國網通的路由表.仔細觀察下,不難發現掩碼位元最高不超過24(即255.255.255.0).事實上24位的掩碼是非常至少,畢竟一個網通的網段裡只劃分了256個ip,已是相當的少了.既然掩碼位元最多隻有24,所以ip的最後一位可以忽略不計,而ip的前3位共有256^3(=16M)的組合.所以將ip的前3位作為key,16M的表長度,正好定義出ip對應網段的表.可以形象如下表示:

  123.0.0.0/24 => Table[123.0.0] = TRUE

  202.0.0.0/16 => Table[202.0.0] = TRUE
                               Table[202.0.1] = TRUE
                               ...
                               Table[202.0.255] = TRUE

   

  檢測的時候取IP前3位,檢測表中對應是否為TRUE即可判斷出此ip的類型.事實上,本例中ip只有電信和網通兩種狀態(非網通網段都當作電信),因此只需1bit即可儲存每個記錄.這時表佔用的記憶體只需16M/8=2M.下面就用ASP來實現這功能.

   

  首先將路由錶轉化成一個2M大小的緩衝表.考慮到ASP的運行速度,這裡事先用c程式直接處理,然後儲存為一個2M的二進位檔案.ASP通過ADBDO.Stream讀取資料流,並緩衝在Appliction集合中.所謂的資料流其實也就是個Byte()陣列變數,可以通過MidB,AscB這類二進位函數來處理.

   

  初始化函數:

Sub Init() 
If LenB(Application("cnc")) Then
ExitSub
EndIf

With Server.CreateObject("ADODB.Stream")
.Type = 1
.Open
.LoadFromFile Server.MapPath("CNC.dat")
Application("cnc") = .Read
.Close
End With
End Sub

  

  通過Appliction集合的緩衝,就不必每次都讀取檔案.2M大小的記憶體也是可以接受的.接著就是分析IP地址,將其前3位轉換成一個數字,因為這裡每個記錄是按位(bit)儲存的,所以還要整除8來對應到Byte()的位置.最後通過Mod運算對應到具體位元組的具體bit上.聽著有些複雜,不過實現起來確是相當的簡單:

Function IPIsCNC(IP) 
Dim arr, val
Dim c

arr = Split(IP, ".")
val = CLng(arr(0)) * 65536 + CLng(arr(1)) * 256 + CLng(arr(2))
c = AscB(MidB(Application("cnc"), val \ 8 + 1, 1))

IPIsCNC = _
(c And2^(val Mod8)) <> 0
End Function

   

  IPIsCNC(IP),返回IP地址是否為網通.
  到此關鍵的兩個函數就大功告成了,接著測試:

Sub Main() 
On Error Resume Next

Init()

If Err Then
Response.Write "系統錯誤: " & Err.Description
Exit Sub
End If

Dim IP
IP = Request.ServerVariables("REMOTE_ADDR")

If IPIsCNC(IP) Then
Response.Write IP & "屬於網通IP"
Else
Response.Write IP & "屬於電信IP"
End If
End Sub

Main

  

  考慮到Init函數需要檔案的讀取,所以添加了錯誤捕捉.不過通常情況下IPIsCNC是不會錯誤的,因為REMOTE_ADDR返回的必然是個正確格式的IP.

  每當訪問ASP時,除了第一次需負載檔案外,其餘時候只需三四行代碼既可以判定,真正實現了空間換時間.

   

  測試地址: http://www.etherdream.com/FunnyScript/IPRange/IP.ASP

  (另附上將路由錶轉換成快取檔案的c代碼:http://www.etherdream.com/FunnyScript/IPRange/IP.c)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.