过期域名预定抢注

 找回密碼
 免费注册

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

[複製鏈接]
發表於 2006-8-10 20:11:53 | 顯示全部樓層 |閱讀模式
有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.
3 x  C5 G# l% g, {9 t1 X$ S: R比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).
+ L4 j( s  z! W4 c5 K0 ]& P要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。+ l7 P( d6 ]6 C4 j
其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下:
* ]; p0 C, k5 n3 ^/ P' f5 e8 d* }'將十進制轉為二進制字符串
! O2 b% x2 f* |( }1 w: dfunction dec2bin(octNumber)! Y. ~8 ~! m& e! @0 _$ O
vara=octNumber
! t% w  O$ j2 Fdo
9 O/ k: e0 B/ T; H0 j2 K( Ndec2bin=cstr(vara mod 2) & dec2bin! g7 e1 f  r" I% J% {& q: d5 T
vara=vara \ 29 y" J: g( y8 h! D/ R) {# ~9 @
loop until vara=0. C1 D% h! }. [" M1 H: X* m
end function
' M1 [: S2 {8 r, M. {( z% W0 Q) \5 f" T0 k
'將二進制字符串填充為8位
/ `' l7 ^9 O/ k3 f7 ^% Z# ~' @' Efunction pad(str)8 }; u. L4 T, u9 }6 k7 M1 I0 g
pad=right("00000000" & str,8)% I& k9 O. Y  t/ V" C
end function
( z& ^- ^* r6 u5 |1 b  d+ E! o3 g3 }; n, ]
'判斷是否是一個IP地址
4 E" d3 r! n* Rfunction isIp(ipadd)0 Z4 L7 Z1 d( l
isIp=false
, p0 Y0 Z; \: g/ Z* Dset oReg=new RegExp
* e) G4 H0 \; @oReg.IgnoreCase=true* N" r1 g( ?% b
oReg.global=true7 _. q  [  V  @6 y, A6 n) d* q
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})"
  W+ m6 R' `8 n( ~4 J' m, f% qif oReg.test(ipadd) then isIp=true
9 q6 e1 }+ {& v5 B7 C& i. vset oReg=nothing, r6 l7 d  R  V- O3 \' K3 P9 W4 z" j' z
end function
0 Q; I# v: v2 g; B7 a" O7 [4 N$ K3 J7 e0 H, `3 P
'其中UserIP是我們要檢測的IP
& S0 m) X- h* A' T6 S: e! x'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
7 m1 x& n2 {. z/ ^( k'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.: H: {! V7 ^1 R$ s
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務
% w1 r+ c/ ~  _0 L1 Y- k3 _'網址:http://www.netInter.cn. G7 q4 e: G5 {5 j# x
'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.( l0 r8 U1 u0 A4 y2 ~5 M% u& C0 X% y- P
; g0 _2 R; l/ V1 b
Function check_ip(UserIp,NetIP)' J7 O: s4 L& F3 a* Z; v
currentip=UserIp+ @* q& E. P  N3 {, C$ Q& r
collection_ips=split(iplist,",";) '將網絡按點分割成4段7 o3 ~; @- O4 `% U6 M' _6 o
check_ip=false '初始函數值,false假設IP不在這網段+ k. z: o& S& @5 `8 C2 Y
NetIP=trim(NetIP)5 Q) ~/ R) `! q
slashPos=inStr(NetIP,"/";); @% B& Z8 k6 l9 K3 B
if slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了3 y4 m* f4 z* M& ]  ?; u9 a
if NetIP=currentip then, I0 [  R6 O4 E* L: X- ^8 Y5 r2 j
check_ip=true 'check_ip=true表示IP相等# D( e- ]; D' S9 M3 E, N
exit function
% m% [+ g- N' m$ b% Xend if
* ?, S: L( A; h8 d3 Selse6 R: f( R% B0 \5 ~* L
netRang=mid(NetIP,slashPos+1) '得到/後邊的數字
9 C3 q# x* r# T/ i9 xif not isNumeric(netRang) then '/後邊不是數字,格式不正確& G; ?) \; z+ y. ^: x% L% }8 C! q  j9 [
exit function
. k5 Q; _* q- zend if% z. ]7 R% Z9 r+ s( X5 M- `! n1 L
netRang=cint(netRang) '將字符轉為數字
2 _! |: w0 Q' }, Q, \if netRang>31 then% G8 ~( a% p% W9 X* d, K9 k
exit function '/後的數字不能超過32位
- d. X# N* D- x: Lend if
& J- H6 ~* P% d6 g0 i, Hipsets=split(currentip,".";) '將用戶IP按點分成四段
9 D$ t, f3 c" j/ ]+ g
0 X. b. L0 M% b) {5 u$ WC_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))6 t1 Z1 d; C( h; f; {5 Z% F
'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制$ s3 D6 X4 g/ h, x) R5 Q6 Q
ipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制& z4 d) p5 W+ c& g( {+ [# i
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字
* {7 S8 H/ l% `; K1 L7 v1 F- e8 _) _if sPos=0 then
, K8 T5 D* u5 P6 E8 t2 v8 j4 @exit function
" x' d) `4 y" ]+ X, z- r( s6 u8 a# Uend if
) U  P" G  K! s( B( F4 ~3 vipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字0 H! h3 M5 J) A! x+ n8 X1 Q* {
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
5 H' D7 ]: m2 B" o: Z) }'將其轉換為32個字符長的二進制; j, @$ w0 V2 F$ E. p
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了
7 O/ \2 i& _$ W! scheck_ip=true3 j, g1 Y; u; ~- ]/ c  {6 `
end if
% [( Z- Y- a$ Z# X; B+ R( F& Kend if* N7 b  h: I' F  ]1 ^) i7 y
end function$ T2 M" V( V$ s5 g9 d/ }

1 K4 E  U/ X2 ]3 ?應用舉例:
4 V* V& E* ]6 L- R4 B/ l. |5 Y8 n
/ J7 @8 Y5 \9 [2 x要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段! D+ c  @- J0 l' s( \
只需要簡單的使用這個函數就可以了,如:
  w" q  o* Z$ S' H
( k+ ]/ A' `0 m5 y& }if check_ip("61.139.1.1","61.139.0.0/16") then0 H. t. _. {9 l7 C5 W0 U7 ]4 }
Response.write "同一網段"* X) D0 N8 x% F% B( O
else
/ y7 N4 C  B" ]! D8 t$ G7 }  _Response.write "不是同一網段"
# ^- E: y/ I1 @end if# a6 h4 [, G. B6 Q& _
; o% m+ ~9 L7 g" x  s
[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ]
您需要登錄後才可以回帖 登錄 | 免费注册

本版積分規則

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

點基跨境 數位編輯創業論壇

GMT+8, 2025-4-17 06:58

By DZ X3.5

小黑屋

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