过期域名预定抢注

 找回密碼
 免费注册

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

[複製鏈接]
發表於 2006-8-10 20:11:53 | 顯示全部樓層 |閱讀模式
有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.
: o, ]3 E2 k# n" a% f比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).( y* @( ^8 A" t% H4 J, y
要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。8 t# |; G' r9 Z( ?. f+ w9 f( J( c
其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下:   [+ ^$ v+ `: R5 a$ J6 n& h
'將十進制轉為二進制字符串4 H% q# o3 O2 j/ n; K
function dec2bin(octNumber)9 Z( ^. b4 J% B/ [
vara=octNumber4 T' b; W7 ^  W$ i' a- v; h
do
3 y1 D  e) b, _; B4 o' k, Pdec2bin=cstr(vara mod 2) & dec2bin
9 ^/ z% W7 M: ^9 Rvara=vara \ 2
% s1 X5 ~* G6 k5 B1 O8 W  f% B6 Ploop until vara=0. E- ]# C0 U& K2 t& Q) j
end function
) q! R) c$ V' w. h( k; W: K3 _( s( ^; H8 x7 Q5 ~+ }
'將二進制字符串填充為8位1 Y+ U$ {8 A  R( O: O  n
function pad(str)( M, j% Z5 [+ O) D9 U1 P
pad=right("00000000" & str,8); l" E5 o+ ~$ c
end function  T4 d+ O" x0 `: f
% R5 C( M6 s8 \
'判斷是否是一個IP地址, `5 A& o+ o; \/ s3 P
function isIp(ipadd)
- }4 K+ Q( K4 t! f: E- EisIp=false, \' x) t/ n& n
set oReg=new RegExp
3 ], p2 i8 t* V5 e/ u9 H4 coReg.IgnoreCase=true
. B9 f* R  ^8 {2 e9 f7 soReg.global=true* j$ O/ Y' u) x2 J
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})"0 X' r2 z8 i( w
if oReg.test(ipadd) then isIp=true
  U7 q; f; h3 c* k0 w6 f9 M* n: Uset oReg=nothing
! h6 Z# }7 D0 e, T8 `% y& {end function
; A! X  g6 z( ~+ j( b( l" T$ _  w" W" `/ D$ E7 t
'其中UserIP是我們要檢測的IP( M* J' z& {6 V( q$ V9 G
'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
4 I5 _0 D. v3 |6 Q: [2 q5 r'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.
; I+ o! f5 x0 q, `" d'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務
, \. K: g* i/ P+ F& O* Q- ['網址:http://www.netInter.cn
$ `* Z2 w: q- ~# q  G) E'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.
. G- V3 h0 ~1 L5 b; W. i" n3 x) W% x+ _% X/ E
Function check_ip(UserIp,NetIP)7 u/ @! }+ {$ w2 G2 R
currentip=UserIp4 ~6 U- m' a2 {! @3 s+ F/ A
collection_ips=split(iplist,",";) '將網絡按點分割成4段
" |6 R; k/ I( W, Pcheck_ip=false '初始函數值,false假設IP不在這網段4 G0 n+ N+ g- V7 T7 ]- B! C
NetIP=trim(NetIP)
5 P! ~: v5 X1 ^! islashPos=inStr(NetIP,"/";)
8 P1 \$ x+ e# _! z4 uif slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了
" D8 h4 `; h4 Fif NetIP=currentip then! V/ D; E1 E- P& M  t
check_ip=true 'check_ip=true表示IP相等4 X5 `. }- e! t! Y7 {& p3 \
exit function4 M+ C, r2 H! M7 X& d2 J  ^! Z7 {
end if& X/ Z+ y. n3 k' L3 ]: U8 P" }% @( n, J
else& |2 s" j# y* z
netRang=mid(NetIP,slashPos+1) '得到/後邊的數字1 {9 o/ a! ?5 E$ n! {; G+ h& O, _
if not isNumeric(netRang) then '/後邊不是數字,格式不正確6 x. i( R/ i& g6 F( C
exit function% S: _" V8 o6 ?  E5 n
end if
2 E% G9 I" E8 n- k; QnetRang=cint(netRang) '將字符轉為數字7 N0 \0 U  Q0 ?3 R9 T9 i+ U9 r
if netRang>31 then
; A$ @6 H+ G3 |+ ]; |% e- G7 l/ D7 Z% Aexit function '/後的數字不能超過32位4 |2 h3 V. [/ I: v3 a* |/ k
end if8 \8 s9 }7 P# U% O6 n0 I
ipsets=split(currentip,".";) '將用戶IP按點分成四段
. V( Y6 {, q* o8 |% P! v% ?: h  F1 |$ Q$ L/ o* X
C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))! Z" u& `0 y% A! w: ]1 m: s' w
'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制" V% U* o# l% X+ `
ipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制8 r% o8 V& L6 ^4 n. `' \4 r* Q
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字
/ a, k* d4 i& R  P4 l- D% ?; Fif sPos=0 then% S1 `9 Y2 u- }4 I7 c
exit function
2 n) x$ [3 |& P6 F* A$ o5 ]* x! c- Pend if
  A" [8 A2 Y& K9 wipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字" V9 ^5 W7 O) j: E" m' {
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))$ `! K! a1 W8 p- O# R
'將其轉換為32個字符長的二進制4 n. |0 m- ]  M+ h6 k( D* M
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了
. \* w$ ^  e: D) acheck_ip=true
* j$ y, }% i, l4 i7 `& Qend if( I5 F& G  l1 j# ]
end if0 y2 W" @6 q. G6 f' z
end function
( j" ]9 x6 o9 d
& z7 K* a& M6 Z9 w# g. ?& t. \0 x應用舉例:
+ R$ m2 k# o  {+ i2 |% u1 s# Q: u  E  l
要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段
6 `# g) K' ^  L- G& K6 ~只需要簡單的使用這個函數就可以了,如:4 H- F) ^: ?$ g$ z+ W0 o' ~( o) L2 B
: M9 `* I& C* |) A: \- x
if check_ip("61.139.1.1","61.139.0.0/16") then
. C# C/ M# |/ m# p2 gResponse.write "同一網段"
3 W8 ~2 g" d" }  W  uelse' S- s: V3 ~/ B9 p# t
Response.write "不是同一網段"
3 S' ~% {$ X& f' x, g2 f8 @- _end if2 U# r' s$ [- M: y4 c

, ~  H0 @9 y# }: l+ _3 r' P[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ]
您需要登錄後才可以回帖 登錄 | 免费注册

本版積分規則

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

GMT+8, 2025-7-12 17:46

By DZ X3.5

小黑屋

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