有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.
2 S3 U8 G: x* z$ P9 \% ~比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).
$ u! u3 t ]/ \5 p3 Y5 H/ Z要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。
& ^5 M; e: E% s" X4 J5 t9 B. K7 P其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下:
0 q8 q; \1 M& T'將十進制轉為二進制字符串! H/ s$ S9 p2 _5 c/ Z% r$ l
function dec2bin(octNumber)
9 M+ `$ \- m3 fvara=octNumber9 v: g% {* e2 L; ~' Q0 I, c2 b' ^
do ; J9 ^! S3 Q N- g+ Y- W
dec2bin=cstr(vara mod 2) & dec2bin
& x7 P0 W* w+ Z3 @5 f2 d; |vara=vara \ 2# E$ Y6 X0 V3 P% W( p8 g, |, v
loop until vara=0- [+ V( d8 i+ v8 a, ^) q
end function8 I9 H4 U1 q, @" G1 o2 K1 e6 s
: j# d' v8 R; x$ k
'將二進制字符串填充為8位
7 w; z" N6 H+ T" `& ?function pad(str)* ]: n& ]: `8 A$ ~- |( p
pad=right("00000000" & str,8)6 R- E" W# U4 R4 d
end function
' r2 F1 w/ K! Y! S% L* B2 j1 W* N
'判斷是否是一個IP地址
6 F' A0 V4 q1 X, u3 g3 `6 Ufunction isIp(ipadd)
9 v! @" L# X# v( N) G. ^isIp=false
6 T% a. r/ s8 dset oReg=new RegExp' B4 Z. K$ t* @1 v
oReg.IgnoreCase=true
4 r( M) c& V+ @/ E$ MoReg.global=true5 s1 h* _/ [$ G Q3 _" Z& @6 e
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})"& h! ~3 |2 X+ Y% t$ D% S9 v B
if oReg.test(ipadd) then isIp=true# q- ]/ F2 ?9 A' S
set oReg=nothing- T! @3 q( h1 U' \$ M" n( h0 x
end function0 u4 r" @2 F0 G. S* b
1 F4 l3 n i9 }8 }' X9 z
'其中UserIP是我們要檢測的IP
* Q. u7 n ^# O# i5 k'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數 ' i" R' Z0 d2 _
'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.; {9 d+ F' O$ l: Y) j
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務
+ K L6 m. p7 e/ A- q1 Y'網址:http://www.netInter.cn8 R# Q! \; z1 ~7 d0 x& ?
'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.
5 |& Y4 y) V) g6 F, t; O" [& Q) {4 C' z; {+ l3 ^
Function check_ip(UserIp,NetIP)
4 `0 ^3 o, L4 W! O+ ]currentip=UserIp' E8 }7 I. b& b9 y
collection_ips=split(iplist,",";) '將網絡按點分割成4段
! ~ j: V/ M+ vcheck_ip=false '初始函數值,false假設IP不在這網段
7 U6 S3 K! D% T9 K4 ^2 }) L7 `NetIP=trim(NetIP)
3 g! `7 Y+ {6 K3 [9 q( \/ w% V9 K( bslashPos=inStr(NetIP,"/";) o* s0 P7 S d k
if slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了
) f; f' [# k f K/ p7 jif NetIP=currentip then8 H: B" J. K' I- O
check_ip=true 'check_ip=true表示IP相等4 w5 [2 |. l: m: D3 i
exit function5 a& B6 x8 ~7 v, |
end if
$ T2 y: d4 r) J2 T; Lelse# }6 D. l2 F( i/ S# c% s" g
netRang=mid(NetIP,slashPos+1) '得到/後邊的數字) w" D, u6 Z* e: `1 G/ o
if not isNumeric(netRang) then '/後邊不是數字,格式不正確3 q/ z$ Q* ^- o9 d9 ?$ c' x
exit function
/ ?: I5 _! R- I7 a$ [2 O; M" `* T9 jend if. L& F# |' G; p# q
netRang=cint(netRang) '將字符轉為數字' f7 ^' C8 H, X' b* F8 p' j
if netRang>31 then" d/ d. `( Z" k; Z& ^% k/ v7 ?3 b. _
exit function '/後的數字不能超過32位& W" i, A$ b1 ^! H. J* @" O
end if" v! s" }$ f% r/ r* b
ipsets=split(currentip,".";) '將用戶IP按點分成四段' v1 L L# j ^6 p, T
3 j* m3 y9 ?" ]/ E# ~" jC_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
8 y/ p# ?3 {! A) Y6 n$ Y& M+ l'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制0 F4 i" f/ S% _' |
ipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制# ?# |4 S. |+ c
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字
, D# g5 @5 Q" ^ Mif sPos=0 then) |; r; i. N5 c6 z$ J- @4 g
exit function+ Y, k! i9 F' N
end if
8 U" y/ j- h0 W: b, p# \ipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字
3 {- k5 r5 q; e" U# u( N3 X8 lS_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
! A. ? X: Y# j2 q'將其轉換為32個字符長的二進制
C7 M% T7 j, Eif left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了7 D1 ~5 e! o" c
check_ip=true6 y( C5 i7 R# w& {
end if6 N8 K5 x" i& T! n9 j7 E
end if! C& Y: \ U% o3 L( C$ D! V! f! c
end function
. R$ v' o( m+ [2 c( O% S$ j& X9 \) \4 X7 h
應用舉例:
?0 u& m3 p3 W( S& M4 j; d4 `1 D% N# }8 E
要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段1 L3 d4 C" S) i
只需要簡單的使用這個函數就可以了,如:9 r3 V# @) K; \1 T
$ n- Y! F7 o% @; r7 s% Q: i2 Oif check_ip("61.139.1.1","61.139.0.0/16") then
9 f. L/ @! r* D6 eResponse.write "同一網段"8 w# d/ N7 a5 d0 I2 ?
else, j1 v5 ^+ E7 ?, E5 n; @1 H7 d. O& M5 F/ n
Response.write "不是同一網段"
4 z X$ z% l% G7 ?; M# X, V1 fend if
2 X! u) K3 m" t) t
- H5 E8 ~- U5 a1 K4 |0 `[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ] |
|