有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.
3 E( E( x1 X% f/ w4 E: R9 X比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).9 E6 {* l. u1 A( G7 L
要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。
& D; V" K- Z: L# M其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下: & ~# w, u0 X4 C
'將十進制轉為二進制字符串+ c O5 {/ L" b, N0 @0 c
function dec2bin(octNumber)
3 h/ g% h' j# Q$ q- U$ C$ v: \vara=octNumber
" n7 I* j0 B) Q& L7 Odo
, A) ~: X6 g$ n9 H9 n( ndec2bin=cstr(vara mod 2) & dec2bin
/ l5 ^4 @: G+ evara=vara \ 2
4 |2 {* y+ U+ Y7 X; G2 yloop until vara=0% ]. B6 F% Y7 b1 }3 X
end function+ W1 O3 U' K) [( _( t
& s' c1 H) |; d2 I'將二進制字符串填充為8位9 a& y* A, h: F, B( H
function pad(str) v% `3 M+ Q/ V9 P W/ ]
pad=right("00000000" & str,8), v2 z, z4 B& D0 o4 s; Z
end function, d9 \2 }/ b4 e& x" Y6 E4 e3 ^5 {9 J
5 j% R1 P0 K: o9 K. N- g4 P G'判斷是否是一個IP地址
3 _; K; w4 [1 {function isIp(ipadd)$ J) W/ R% J8 s: E
isIp=false
) I( e# s4 Y2 N' @! ~5 H. u5 mset oReg=new RegExp# w5 P4 G2 t! z- h
oReg.IgnoreCase=true: Q+ I+ _* I1 Y! {, r3 i# E
oReg.global=true
" }, Q2 d: D$ Y, i% K( boReg.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})"9 a0 J( B# D; `' d4 V1 {+ i
if oReg.test(ipadd) then isIp=true5 i3 {9 C1 B) r1 I1 j
set oReg=nothing1 R, n1 t9 ^5 p$ ?- f ?
end function
' _, `# A. n1 m7 Q2 Q/ D) c" S, ~) H$ x
'其中UserIP是我們要檢測的IP
3 o: U1 Y) H) V. F'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
1 B4 Q2 J9 z5 [0 x0 t'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.9 @- s9 F( a, j+ v# L7 e g' V
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務. y' |6 U7 N% W1 ~2 W3 }
'網址:http://www.netInter.cn: F- B5 j6 I. E* ?0 d/ \: U+ j
'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.3 @: c: w# a. {$ x
) x$ d% |7 k# q7 F# ~
Function check_ip(UserIp,NetIP) a' `+ r& i; N" R. o4 ?
currentip=UserIp; O1 @1 O: B# P
collection_ips=split(iplist,",";) '將網絡按點分割成4段5 K/ w6 R$ ?* v
check_ip=false '初始函數值,false假設IP不在這網段, |2 O' p' }6 [! U3 [% p; [ f, ?5 b
NetIP=trim(NetIP)
9 e9 N: w% T2 D0 |- v) `slashPos=inStr(NetIP,"/";)2 T: G# I" ]& V4 R- A& w0 o4 u
if slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了/ X# v% V: w8 o0 f+ a
if NetIP=currentip then5 a9 k8 f! J m" v& m, D8 z* a
check_ip=true 'check_ip=true表示IP相等4 {5 @' L G# O
exit function. J+ t, n% W. I
end if; f; y( d' x- @! S% t
else4 W9 L1 d+ N; q' B& k5 [' r
netRang=mid(NetIP,slashPos+1) '得到/後邊的數字
: v6 R) y5 L# A9 S! @if not isNumeric(netRang) then '/後邊不是數字,格式不正確
* r# d, r: @+ }# Rexit function
( H/ I- r4 A# Cend if
?; ~& m5 U: ]+ C# t2 `" c" enetRang=cint(netRang) '將字符轉為數字' I' a: Z9 _: j4 q1 o( P
if netRang>31 then& Z& K M: U6 V; Y, {
exit function '/後的數字不能超過32位
0 Z3 t$ _3 q m: \- R7 C7 K. {end if
* t" n* X, P7 E4 t! w# v+ {- f, oipsets=split(currentip,".";) '將用戶IP按點分成四段1 L" M; Z* G1 s8 }! v$ i
& C, w( W$ E b u
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3))). L" `. N3 e7 c+ h" P4 l, n
'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制
/ r# Q- I' _/ ]5 v; o3 Ripsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制# K/ O; S$ p4 y6 e
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字" A; U- L0 E+ i4 C( U/ W
if sPos=0 then, a5 l6 a! ]# _- J. }
exit function5 L% g$ g D& ?8 _2 b
end if
g# U6 n/ |( i8 U: h0 c& pipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字: u `# i3 I [* R: H9 X B
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
* y9 K) @, u- u'將其轉換為32個字符長的二進制& r% b1 }! y' |* I
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了) {$ l- r$ _9 V) t8 u
check_ip=true
0 d. e( \4 D. g9 h! Kend if4 ^$ l: D% c! t6 l* V
end if
. K4 J, o# p, V2 M- ^end function
6 x2 N0 u) K5 P! ?/ m" R
( F l- c: h1 k, X C應用舉例:
1 V V$ X9 ^2 a' V9 V
. B. K* R; G/ ^) v/ U+ E, _( C要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段, z4 ^( l! w( k k% w2 l1 ]: T3 W
只需要簡單的使用這個函數就可以了,如:
: Q: |6 B# h& r
1 t V2 I4 v/ v; ?, A7 h: ^if check_ip("61.139.1.1","61.139.0.0/16") then
. G0 [7 l0 C5 |2 N& h3 l; ^Response.write "同一網段"
/ s+ f0 q8 e, m- W, ?) S, t% L3 |else
1 D, j$ N% C7 o% QResponse.write "不是同一網段"
/ B. x, P! \: F* fend if
4 [, O/ I* ?; |0 [. V* Z) z- o
, E2 |; L2 x9 C4 d[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ] |
|