过期域名预定抢注

 找回密碼
 免费注册

用asp判斷某IP是否屬於某網段的另類算法

[複製鏈接]
發表於 2006-8-10 20:11:53 | 顯示全部樓層 |閱讀模式
有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.
5 x2 p6 g! r3 {: H比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).# ~( e# w% x+ n
要實現這樣的功能,現在流行的算法是將218.6.0.0和218.6.7.7按256進制換算成10進制並進行比較得出,如先計算出218.6.0.0和218.6.255.255的十進制:218×256×256×256+6×256×256=3657826304,218×256×256×256+6×256×256+255×256×256+255=3657891839。再計算出218.6.7.7的十進:218×256×256×256+6×256×256+7×256+7=3657828103,最後再比較3657828103是否大於等於3657826304和小於等於3657891839。但明顯有一個問題,計算量非常多,值非常大,如果IP地址是61開頭的還好,如果是218開頭的,這將會造成數據溢出而出錯。( M2 F/ f2 |; i& r
其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下: ; I( b( K, O) O
'將十進制轉為二進制字符串
1 d1 Y" Y: h+ ~2 Y# ?function dec2bin(octNumber)" c& e4 h, k4 @$ Y4 M/ B
vara=octNumber
9 r( Y; \! b: O$ ^6 q% Pdo
4 c( \6 H: K8 _7 j9 R; n$ Q: rdec2bin=cstr(vara mod 2) & dec2bin( {7 ?3 D- E( w$ c/ A
vara=vara \ 2( U( y1 ~+ j! e$ y( ]2 B9 Z
loop until vara=0
7 c/ m7 T) O8 ?2 t- gend function
+ k7 `( N# D% B! |% {, l$ ?
$ ~2 U: k( C/ I9 R'將二進制字符串填充為8位4 [4 J, p$ T9 h3 d1 N4 i" \
function pad(str)1 r2 F# U; A5 z3 p( v
pad=right("00000000" & str,8)  z0 f3 B9 T" K/ d( O$ E2 V
end function
% E+ O  q- r1 L+ Q; X! T0 }/ m6 i
* ~  o  U; S2 E8 i3 _0 K8 a'判斷是否是一個IP地址
0 Y! D/ o7 w' F4 e6 J! Sfunction isIp(ipadd)
/ M8 o/ ^# {6 s, lisIp=false$ y& h: e6 H& _# H
set oReg=new RegExp
( ^! L9 w8 M" j$ i9 W6 A- j8 WoReg.IgnoreCase=true
# E& W/ v4 I- g8 _+ _, q+ moReg.global=true) Y( t" `. }: \" M
oReg.Pattern="(\d{1,4}\.\d{1,4}\.\d{1,4}\.\d{1,4})|(\d{1,4}\.\d{1,4}\.\d{1,4}\.\d{1,4}\/\d{1,2})"
/ ^* s$ U$ ]5 P- `% tif oReg.test(ipadd) then isIp=true8 O. e* b! z! V, K" L+ X
set oReg=nothing1 h4 C" w/ w) u* f
end function: y2 e' z: _+ U
) m( U! h  B. f- u
'其中UserIP是我們要檢測的IP4 C6 f& h9 g8 B& _8 A. |
'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
& M9 p( I: Q% r3 v5 j'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.
6 E/ f7 L+ B' `) {'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務6 S; S- w8 x" d0 p) ?" l+ \* }
'網址:http://www.netInter.cn/ y4 H! F# q$ l$ n( |: H
'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.
9 S" Z0 H0 G1 g5 d4 w# E6 }: T. o/ y& n- O' y; ?' y
Function check_ip(UserIp,NetIP)
( M2 K7 C$ R' A! b. ucurrentip=UserIp4 m6 F6 t2 g, i7 D
collection_ips=split(iplist,",";) '將網絡按點分割成4段
; ?$ q9 E# E1 u* D' ]check_ip=false '初始函數值,false假設IP不在這網段6 k0 v/ k. z: |
NetIP=trim(NetIP)
" z' f; }; ^" xslashPos=inStr(NetIP,"/";)
; @+ d0 Z4 D& F+ [! ~! V) `$ t/ ?if slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了, C6 i+ L$ ?" C6 I& O% N5 T
if NetIP=currentip then
# i1 @1 C/ A1 v# K6 y! o! dcheck_ip=true 'check_ip=true表示IP相等
4 _0 B- T' R' E) t' l) ~; a5 [exit function; s* B& G' E. W( ?
end if8 L% E$ I' k; b4 O' E3 S( G
else
9 v& }$ k+ j) ~9 `: m6 ynetRang=mid(NetIP,slashPos+1) '得到/後邊的數字
( s* G4 K3 ^' O3 e  T4 B" B- Xif not isNumeric(netRang) then '/後邊不是數字,格式不正確: X% ?* i* w7 e! {# C+ P$ E
exit function6 T% H! x, S5 g3 S
end if+ E, z: h, \& L: o
netRang=cint(netRang) '將字符轉為數字9 F* G" [! @+ ~1 z
if netRang>31 then. z" U! d: w8 G4 j5 o0 J0 }$ f
exit function '/後的數字不能超過32位+ x# [4 |+ r! E, m! x
end if1 O% `# p+ N% F) e1 \7 g
ipsets=split(currentip,".";) '將用戶IP按點分成四段0 Y# w  D( _' m0 [( ^! S
4 {5 M0 K. R  K- w
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))3 P$ i/ n2 n, J8 `
'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制
$ m1 d' l  X  m- B+ o( bipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制
. B5 p4 h. V/ D$ |% }% w$ n5 }8 x( [sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字" M' v4 E5 n9 v3 b. g7 R: J' ~
if sPos=0 then
# B6 j& h. a6 \3 E8 \exit function
3 y5 X5 J' o; i# oend if# p. D- Z9 E; X% o( Z$ O
ipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字
" E/ W$ L9 D8 u. j) k$ W5 s! VS_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
" C0 Y& j' J$ D5 a'將其轉換為32個字符長的二進制
% ^4 i1 D7 \0 `- A( T$ Y7 Jif left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了5 \! t5 E& k: d" R$ p+ G
check_ip=true
6 _0 l' h  V* r6 G/ Eend if
3 O$ S1 v- s+ z, Mend if: R; g  \! @  }: \+ j
end function3 H/ u* F( S& c! r, u

* ]( B& T7 c: w( y6 p應用舉例:
5 A. X3 @" N/ Z& E+ j& A' a7 J; K
" Y" O4 C- E; H6 _1 K+ V6 k. I& x要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段: q4 O- a, s6 X$ H( e6 P+ q! A
只需要簡單的使用這個函數就可以了,如:
) X; `* a. M' Y; M& Q9 o
0 F* E, C# d$ t/ d7 Gif check_ip("61.139.1.1","61.139.0.0/16") then
1 X2 V- \1 B! d- e7 h  R+ J1 U+ bResponse.write "同一網段"# k( s3 |+ P* A
else: O$ b: @4 |# M. r5 y6 F0 u
Response.write "不是同一網段"# R. }9 d9 ~1 T6 s+ q! }! ?9 S0 P
end if( U. G. ~" ]: K# ?

5 V; {* w2 Q4 n; U7 V[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ]
您需要登錄後才可以回帖 登錄 | 免费注册

本版積分規則

过期高净值品牌域名预定抢注

點基

GMT+8, 2026-1-28 08:11

By DZ X3.5

小黑屋

快速回復 返回頂部 返回列表