过期域名预定抢注

 找回密碼
 免费注册

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

[複製鏈接]
發表於 2006-8-10 20:11:53 | 顯示全部樓層 |閱讀模式
有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.) c: e; ^3 Y6 y: h; _6 p
比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).9 B' c" b, K- t; v
要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。
- Q1 Z( g+ z, A& E( c# R- ]其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下: 2 d! y- x+ b2 R+ `; ^- v+ |
'將十進制轉為二進制字符串
9 }9 H2 [3 O) o( P2 Xfunction dec2bin(octNumber)& w. p$ p! o8 [4 \( k
vara=octNumber
* i2 M: s, r" udo . {5 P3 j0 r: S5 R
dec2bin=cstr(vara mod 2) & dec2bin
7 F* j/ S- J; ]8 N* k% Pvara=vara \ 2
! [6 M1 u2 I( H1 Z# j" S; o% t( bloop until vara=0* I; j3 _1 C$ ?; o' N
end function7 Z; f; q# E0 z  g
. D% y$ ^5 l$ S2 }5 x; ]
'將二進制字符串填充為8位- I; v: K1 K$ i5 H( C
function pad(str)4 M3 y# [+ h5 N" q+ i8 N
pad=right("00000000" & str,8)
) A# |2 O) [) [" T' b  Gend function
+ a3 m3 b) G& E: B& M3 J$ @. e  p/ l/ e  |  p6 u4 t. D0 d/ Z* M
'判斷是否是一個IP地址
$ \( s! M+ h7 m2 J4 B( r+ \' B7 |" Efunction isIp(ipadd)' P& [6 T4 A) r: W
isIp=false
, V9 U% j: N, @% z2 Uset oReg=new RegExp  B) l" [; ^5 ^% I3 U. D* d
oReg.IgnoreCase=true
( r) R: Y1 Z; h8 ~+ E4 soReg.global=true6 y+ `9 ]0 F, b  c; g+ X& h8 Y
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})"
: f6 I6 e2 v* u" {! l; M8 Rif oReg.test(ipadd) then isIp=true
6 l/ u+ x7 u7 l/ r' b# `9 Pset oReg=nothing
  T1 {% h! E5 E2 j2 Rend function
2 ^( q! T0 F3 W" Y; q8 ~8 Y
7 S" o) g3 `$ ?, f1 S'其中UserIP是我們要檢測的IP
; {# m8 O  S' V5 q'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
; |5 k4 u8 \* N4 F1 D- p: J'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.3 e' \+ [4 y4 q
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務' o8 |& n) F# V+ ]/ }
'網址:http://www.netInter.cn
9 g7 |: O' e; I- @, A; i'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.7 e( e( `+ F/ l. P

$ v2 D" p  `: p1 wFunction check_ip(UserIp,NetIP)1 K9 o) u# p+ K
currentip=UserIp
0 w0 a4 ]2 }3 Q3 l% ]8 T0 h' q0 Dcollection_ips=split(iplist,",";) '將網絡按點分割成4段3 c# Z/ v+ l/ E" p9 ?2 F
check_ip=false '初始函數值,false假設IP不在這網段
7 N) G6 [6 u( \! cNetIP=trim(NetIP)( g: v6 I. N  o) T, Z, d
slashPos=inStr(NetIP,"/";)( T4 K5 Y: h, A  h5 \: [0 T
if slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了/ y; d5 C9 l' u7 T
if NetIP=currentip then
' q6 P) M0 D3 c* p; Q3 xcheck_ip=true 'check_ip=true表示IP相等
) C' n( r9 W) v2 Q  `' _% bexit function. S( l* G* ?1 [; C- l
end if
/ g; t  ~5 _6 Y, h0 helse0 U# t+ p, m% O! _' a* o
netRang=mid(NetIP,slashPos+1) '得到/後邊的數字. `1 [: {8 p) O" @/ W7 ^+ h
if not isNumeric(netRang) then '/後邊不是數字,格式不正確" _& H- ]9 e. v% o8 S; |! ]6 c
exit function
& E: W/ R- p6 H3 kend if- ]% Y; C7 m5 }8 Z, s
netRang=cint(netRang) '將字符轉為數字
# b% q  k: `2 `if netRang>31 then, ~4 f1 U& t1 v: W  k& N
exit function '/後的數字不能超過32位6 m  |3 j8 z3 q4 J
end if# f5 {' R' V5 t7 v* G
ipsets=split(currentip,".";) '將用戶IP按點分成四段
' w3 _3 z! C- i# \% o
( V% ]6 x1 r( S; x$ sC_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
! d2 Q9 I3 j& a& p: `" ]7 @'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制
% R3 y* u6 V* Z* Y) Xipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制" }& d- W. A7 w! ?/ p  T
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字7 o, e( I  m9 v# M$ c( D  [# h
if sPos=0 then
" o. A) H" H8 G6 N+ b: vexit function
/ D, M6 S  s0 K: c9 x% }end if+ w# N, y/ j& }8 |4 m0 y" j- P2 p
ipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字' `  `  ~- F1 }% U$ @1 K. [4 `
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
, s$ \$ l2 R. L# V5 ~( ^+ c5 r'將其轉換為32個字符長的二進制
6 X0 C: j' |- @; p+ Xif left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了# r; _  F! e6 Z
check_ip=true. ~0 A6 F4 E. [! |4 X
end if
0 }& j" K7 O9 ?: q- U" dend if: w4 E2 c1 s. D' D! B4 L) H6 j
end function
; j% H# Y" c! _8 V) |+ F# z5 d% `6 F3 H  L4 P4 C
應用舉例:0 o  m9 g% t1 p2 D- J( _

0 V# {" m* ?% E要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段
3 e) ~% z* \+ L1 c6 D# n9 K7 b只需要簡單的使用這個函數就可以了,如:
( {- P! i- c  ]3 a  ]4 x9 `2 A  Q/ m
if check_ip("61.139.1.1","61.139.0.0/16") then( V4 t7 o; z* P5 ], [! C" U
Response.write "同一網段"0 s& D0 V/ B9 [  ?8 a
else
* ?% _; P. r* M, G% m' AResponse.write "不是同一網段"- L: s6 d: q0 @4 F, J/ e
end if
5 S) n8 M; j& U4 f8 f6 T
/ V0 G1 a- @/ ~& P" R" W& x[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ]
您需要登錄後才可以回帖 登錄 | 免费注册

本版積分規則

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

GMT+8, 2025-5-10 06:39

By DZ X3.5

小黑屋

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