有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.0 r: Q6 O+ F( Q+ s7 T
比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).* |$ B# o4 z4 R# P5 m( i: R/ Q
要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。
* G4 n* e) N2 Y, K c. f其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下: & R9 d9 e' B0 x$ q W) X" h' B
'將十進制轉為二進制字符串( c9 r& Y* h3 p/ f; V2 O- w/ f# W
function dec2bin(octNumber) M, l' R, B: s" _8 I
vara=octNumber
7 U( y& O. K6 |' q7 ~; P% o; ddo
1 L% \" G; D% E0 @2 B$ _4 Y& r# Xdec2bin=cstr(vara mod 2) & dec2bin$ m j/ l j* }$ y) E' q8 _
vara=vara \ 2
1 F$ p8 r4 A1 ploop until vara=0
% M% k0 @) Q' h& l( Yend function- o; s/ M8 ` |- }; N1 G- X. h
8 a6 a- V# n' S, g7 J( D! t9 C3 T
'將二進制字符串填充為8位% a: j$ X; F. g: r# t4 d
function pad(str). T: ]- g( D# p
pad=right("00000000" & str,8) o- Z* h% G$ g, i z
end function- t* e+ K0 [% k( E$ _' r
. A. R9 a5 r1 z* x/ p
'判斷是否是一個IP地址$ c5 T4 r: C% C
function isIp(ipadd)- ^% A' G/ H$ ^
isIp=false8 x5 T2 K% R5 K8 c& w$ W5 c9 ~* x" ]
set oReg=new RegExp9 j6 m7 C! l6 p! ^( |" n3 `
oReg.IgnoreCase=true
, H3 h7 Q1 N' b* yoReg.global=true. t7 h& Q' w6 Y# G
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})"
1 Y/ [- j: I: H" G! jif oReg.test(ipadd) then isIp=true
, O2 y C. T) w0 }- e1 Mset oReg=nothing' H e# U" _2 H/ {) T& X
end function ]) ^1 V; }( @/ V8 Y$ \
3 y$ ]7 R" [3 u7 f'其中UserIP是我們要檢測的IP
8 l( J* o$ ^9 h5 T( U'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
9 |1 q% s, ]( t/ H: [1 t8 f7 M'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.9 u4 d6 a, x/ e! N4 e& P
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務! R' d; F* ~. |
'網址:http://www.netInter.cn# Q, O4 X. K. \/ E4 p4 U/ S
'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.
0 W+ N/ I) h9 |. ~* J. N# F! z6 z. i: z6 M0 [6 o
Function check_ip(UserIp,NetIP)
: D8 C9 _ |, S) |# y+ A" ncurrentip=UserIp. V: d; V5 ^* ?- `% A
collection_ips=split(iplist,",";) '將網絡按點分割成4段
3 J6 w% A3 W) q' T; ?8 }5 K/ i- Echeck_ip=false '初始函數值,false假設IP不在這網段! i. j5 Q1 T, v
NetIP=trim(NetIP)
S B- i3 e, J7 y" ^5 OslashPos=inStr(NetIP,"/";)
( X% f8 k3 e% q) c' v1 dif slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了
+ K& q3 _% b+ n2 D0 Uif NetIP=currentip then
- y$ L5 ^- g) g( i! scheck_ip=true 'check_ip=true表示IP相等' p1 \; p$ U/ \( d% H3 }
exit function
8 O$ b5 |& U! R* Z2 y a6 r# hend if# P7 W5 \( ?2 e9 L
else
# |; i( _; {4 H* N9 ZnetRang=mid(NetIP,slashPos+1) '得到/後邊的數字
1 S" j9 a8 E2 d$ _if not isNumeric(netRang) then '/後邊不是數字,格式不正確
& q3 B; J0 r0 v* rexit function# P4 ^6 M" E+ m% H
end if
1 Z, e, y2 f5 m, ]2 h: TnetRang=cint(netRang) '將字符轉為數字
' Y5 x, A# Y; \( E# \& sif netRang>31 then
, z. c- p- s- ^* xexit function '/後的數字不能超過32位* S2 o5 { L: U/ U
end if
4 V& g% o( \" v* o: A" M6 Z% G0 dipsets=split(currentip,".";) '將用戶IP按點分成四段' `* v( [: o/ i7 V
* ]- x j9 O: ]+ Y
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))# t9 R0 n4 I! f$ e0 Y0 w4 K+ k
'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制
2 l y; M* R7 J. I; Pipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制- ]- ~ m$ K6 U# u
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字
! a$ e1 ?$ K! S# T5 oif sPos=0 then
# c. T9 ?0 w; |6 E8 Rexit function
! U f2 K# Y d8 Hend if
! U$ d8 T7 @) {6 L+ G2 Q/ {. c8 wipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字
1 f% C' V/ [$ g I5 H, Z" ^2 r6 BS_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))) d+ m' p5 t/ \
'將其轉換為32個字符長的二進制1 C/ P6 M, w* v8 L2 n
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了
& A9 b6 C. Q8 ~! J5 Ccheck_ip=true2 E/ J1 e$ p2 D3 G3 e3 W& z
end if% j7 L& y% A2 A" M9 o$ ^* p4 j
end if
( l" g9 e2 S. _end function
3 i3 m0 O7 y0 u" p9 h2 p) ~, r' P0 u t
應用舉例:
& Q9 z4 R. Y) H# I
9 `/ v/ M& [: B要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段
9 E0 ~) t5 R* C/ Z7 l只需要簡單的使用這個函數就可以了,如:+ R- T- a& g; `6 S
2 M& M4 }- x8 u* z' [0 u
if check_ip("61.139.1.1","61.139.0.0/16") then
4 f$ u l' b, z8 x; j$ n1 ]Response.write "同一網段"7 v* X! A5 X7 \; s- d, ]
else
5 \9 m K- H' G9 pResponse.write "不是同一網段"
l7 C7 @' U: k# e( V- N+ @& g8 Aend if# ^2 }8 W+ X4 _. z- ?
. T9 h! F( I' `/ P[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ] |
|