过期域名预定抢注

 找回密碼
 免费注册

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

[複製鏈接]
發表於 2006-8-10 20:11:53 | 顯示全部樓層 |閱讀模式
有時候我們需要判斷某一個IP地址是否屬於一個網段,以決定該用戶能否訪問系統.4 X. J2 n5 U6 l
比如用戶登錄的IP是218.6.7.7,而我們的程序必須判斷他是否屬於218.6.0.0/16這個網段(其中/16是新的子網掩碼的表示方式,相當於255.255.0.0).
3 M9 j# @( {/ W. u6 A6 u& C0 s- @要實現這樣的功能,現在流行的算法是將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開頭的,這將會造成數據溢出而出錯。
  c2 a1 T- h/ L: G+ I其實比較IP是否屬於某一網段,最好的方式就是將IP與網段分別轉為32位二進制,再比較他們的網絡部分是否相同就可以了.asp本身不具備位運行功能,所以要實現這個只有我們手工實現,具體如下:
- F# p9 @4 f" A4 L/ w'將十進制轉為二進制字符串
" _% E2 P( V# G7 S5 lfunction dec2bin(octNumber): P2 g, E$ ]8 r
vara=octNumber  d8 t. h- E/ J% ~: Q
do
9 O3 L" i, n/ Adec2bin=cstr(vara mod 2) & dec2bin5 z7 Z8 a6 F; i1 g2 m
vara=vara \ 20 w7 n: O) _- B- I# }: [
loop until vara=0, [6 f& `% k/ O0 r3 J( `# H
end function; m4 g+ n) D) f3 e6 D; }1 @
8 {, h) J/ f3 D3 Z
'將二進制字符串填充為8位. M( s7 e* G) e% L3 k
function pad(str). E- h! Z0 \; i
pad=right("00000000" & str,8)
+ T/ y: g7 ]+ Y% ?! mend function3 N9 i7 N9 a) s) a. z
3 c* s8 X- Q4 ]" ]. ~/ X
'判斷是否是一個IP地址6 F) M5 g5 W/ e; [
function isIp(ipadd)3 |! j4 h" F1 Q) a( A
isIp=false; u* ]8 L) r2 w/ y$ m
set oReg=new RegExp
. L/ \$ h3 w" E6 y4 o  Y- doReg.IgnoreCase=true
! C0 o- e' ^, B+ joReg.global=true# p6 `+ j! g; @( H
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})"
$ K% D+ k$ `- Y# Bif oReg.test(ipadd) then isIp=true* M1 v+ l4 I. d  N' D1 A3 H/ ?
set oReg=nothing
7 A- q) @$ x# u1 d- vend function
. d/ S3 t! U3 x- u# W- v
* }9 k1 R9 S$ x  r'其中UserIP是我們要檢測的IP/ B; }1 B. {  B- K, h: X3 P
'NetIP是要檢測的網段或某個IP,用xxx.xxx.xxx.xxx/N來表示網段,其中N表示子網掩碼位數
) [) X2 }4 Q7 T2 D- x  x'注,該程序是環球萬維原創程序,所以如果您要轉載,請保留出處信息,謝謝.$ r7 ~8 J  z/ E3 L. k; q
'程序設計:環球萬維,專業提供域名註冊,虛擬主機服務
% A' B. p1 C; @'網址:http://www.netInter.cn
2 N; c8 m' g7 s& ^& B0 r- ?'以上信息與文章正文是不可分割的一部分,所以如果您要轉載本文章,您必須保留以上信息.
8 ]9 R' y  b, W. R8 X/ E. S" P$ y7 C: f" ?; r8 W
Function check_ip(UserIp,NetIP)# a0 ~6 E" G* `3 F6 L/ A
currentip=UserIp+ E& K' x* {, U$ E
collection_ips=split(iplist,",";) '將網絡按點分割成4段4 V% H7 N! J( \; g' }1 G
check_ip=false '初始函數值,false假設IP不在這網段% O) D6 N# \9 f- `
NetIP=trim(NetIP)
  y* b! d/ l& l1 W3 L3 D( lslashPos=inStr(NetIP,"/";)
$ T& v( {$ a3 |* m6 g1 M+ dif slashPos=0 then '網段沒含有/符號,他只是一個IP,所以比較比個字符串是否相同就可以了
- l! d" @, Y9 X8 p1 w; Sif NetIP=currentip then6 Q0 i. d4 C, W% o0 ?4 e, H/ e
check_ip=true 'check_ip=true表示IP相等
% N2 W: P9 z* t; n( ], oexit function; {& g9 ~3 Y* |
end if2 D2 I5 o9 P2 G, D1 ]. s- \
else
) I! B! G, b3 }; A4 inetRang=mid(NetIP,slashPos+1) '得到/後邊的數字
$ f% I5 e5 Y4 Q8 oif not isNumeric(netRang) then '/後邊不是數字,格式不正確! E+ a8 n* w2 Y2 Y9 L/ g- y
exit function
1 d/ f4 U# L2 M0 m/ y( D  X5 wend if4 }) ]9 W3 }. J, e; v1 C. Q) ^
netRang=cint(netRang) '將字符轉為數字
  T! q( g5 u1 M5 `& K9 ?1 k8 jif netRang>31 then- D) ?$ a4 F2 ^, |8 s
exit function '/後的數字不能超過32位' X4 L3 I5 v2 V: M: K0 p! Q
end if
4 x- h) y. a4 c- L% @ipsets=split(currentip,".";) '將用戶IP按點分成四段+ |0 l3 e2 B8 ?# u  J3 E

/ |4 O& ~5 J+ VC_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
4 F& k- T7 H& T' _3 u- ?3 z+ T'上邊這行是將用戶IP地址手工轉換為對應的一個32個字符長的二進制3 ~1 f6 t: Y2 m) e+ W# a. l( @  W9 F
ipsets=split(NetIP,".") '按上邊的過程將網段IP同樣轉為32個字符長的二進制; V* V7 l- H6 j; F, P( m
sPos=instr(ipsets(3),"/") '最後一點格式應該是 數字/數字0 ^; T, E; T$ y& Z  E& z, Q8 V
if sPos=0 then
5 e( y3 [9 q: q/ v( Z7 {exit function
6 b, X" o( S; C  yend if
# }) O( g( z' c3 Q( p2 Yipsets(3)=left(ipsets(3),sPos-1) '得到最後一段/前邊的數字
6 F- U+ c- }0 A% ~S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
2 `8 c2 W6 l9 n% f'將其轉換為32個字符長的二進制# _+ J0 h) d' T
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比較網段絡是否相同就可以判斷用戶IP否屬於某個網段了
! n' ^4 r) }: j3 Hcheck_ip=true
) B% A6 G: d. z7 E% l% W4 k0 `9 Send if
3 H; o  ~1 g$ g1 U2 U2 j2 eend if
+ M8 ?# W& S9 I: Z! j! z  I% aend function( A  k' w, c% O: d8 O* K% i

5 I4 W% Q& t* O& |應用舉例:9 H4 x3 K/ [4 n. [
' m# c! E3 U7 r  a# T" c" i; ]
要判斷61.139.1.1是否在61.139.0.0/16 (255.255.0.0)這個網段
% {/ b1 \2 t( M只需要簡單的使用這個函數就可以了,如:) V$ Y4 h7 {- g4 b! o% E
$ y3 s8 h9 ?1 }! r% R, V
if check_ip("61.139.1.1","61.139.0.0/16") then
8 ^9 o7 }) s: q* r$ wResponse.write "同一網段"
/ {" ~1 O" k- _# m: Yelse
6 J+ p/ x1 l1 N- h, pResponse.write "不是同一網段"
6 C% I* D1 J( F  xend if
. }3 p* N! A3 M# l" j; D  u& L/ z; Y$ [
[ 本帖最後由 鼕菇蒸雞 於 2006-8-10 20:13 編輯 ]
您需要登錄後才可以回帖 登錄 | 免费注册

本版積分規則

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

GMT+8, 2025-5-9 20:46

By DZ X3.5

小黑屋

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