用ASP编写一个新闻管理系统,前台的某些新闻的正文限制在本地区或本部门浏览,并非限制整个网站。新闻管理人员也无法频繁地在网站服务器上设置权限,而且要求限定在某些固定IP登录,进行后台管理。于是编写了一个限制IP地址的ASP函数,能同时支持如下7种不同格式的范围IP及其组合(只需一条规则,就能限制任意IP范围):
1、单个IP 例如:11.22.33.44:允许,11.22.33.45:拒绝
2、宽范围* 例如:11.22.3*.*:拒绝
3、区间- 例如:11.22.30-40.0:允许
4、之间~ 例如:11.22.33.44~11.22.44.33:允许
5、子网掩码/ 例如:11.22.33.0/255.255.255.0:拒绝
6、子网掩码位数 /CIDR 例如:11.22.33.0/23:拒绝,11.22.33.44/27:允许
7、IP限制库文件 #ip.txt 例如:#ip.txt:允许
其中ip.txt是用换行分隔的IP限制库,内容如:
58.14.0.0~58.25.255.255
58.30.0.0~58.63.255.255
58.116.0.0~58.119.255.255
一次性添加如下内容,就不必经常改写网页代码,用户只要提交表单来管理新闻。
例如在User表中加IP字段,内容如 "10.0.0.2-14:允许登录" ,就实现了对新闻管理组用户(固定IP 10.0.0.2-14)的登录绑定。
再如在News表中加IP字段,内容如 "10.0.33-55.0:允许浏览" ,就能实现让某些新闻的正文限制在本地区或本部门浏览。
添加网页代码:
If CheckIp ( getIP() , rs("IP") ) then
'允许登录 或 允许浏览网页正文
Else
'拒绝登录 或 浏览
End if
详见:http://blog.csdn.net/tsxnb/archive/2009/06/23/4291710.aspx
<%
Response.Write "限制7种范围IP的ASP自定义函数 测试演示:<BR>"
cInput_Ip="11.22.33.44" '待检查的ip
cBound_Ip="11.22.3*.*:允许,11.22.30-40.0:拒绝,11.22.33.44:允许" '给定的范围(支持7种格式)
Response.Write "待检查的ip是 "& cInput_Ip &"<BR>"
Response.Write "给定的范围是 "& cBound_Ip &"<BR><BR>"
if CheckIp(cInput_Ip,cBound_Ip) then
response.write "登录成功<BR>"
else
response.write "您的ip不被允许<BR>"
end if
'************************************************************
'Function CheckIp(cInput_Ip,cBound_Ip)
'功能:限制7种范围IP的ASP自定义函数(只需一条规则,就能限制任意IP范围)。
'Created by tsxnb , 392324126@qq.com 2009.8.1 参考qqdao兼容旧版本。
'参数:
'cInput_Ip,是待检查的ip。在实际应用中就是客户端IP地址,由getIP()获得。
'cBound_Ip,是给定的范围,可以存到库里,格式为单个ip和范围ip,多个范围用逗号,或换行分隔。支持的格式有:
' 1、单个IP 例如:11.22.33.44:允许,11.22.33.45:拒绝
' 2、宽范围* 例如:11.22.3*.*:拒绝
' 3、区间- 例如:11.22.30-40.0:允许
' 4、之间~ 例如:11.22.33.44~11.22.44.33:允许
' 5、子网掩码/ 例如:11.22.33.0/255.255.255.0:拒绝
' 6、子网掩码位数 /CIDR 例如:11.22.33.0/23:拒绝,11.22.33.44/27:允许
' 7、IP限制库文件 #ip.txt 例如:#ip白名单.txt:允许
' 其中ip.txt是用换行分隔的IP限制库,内容如:
' 58.14.0.0~58.25.255.255
' 58.30.0.0~58.63.255.255
' 58.116.0.0~58.119.255.255
' 举例 只允许IP 11.22.33.44登录 "11.22.33.44:允许"
' 举例 只拒绝IP 11.22.33.44登录 "*.*.*.*:允许,11.22.33.44:拒绝"
' 举例 多种组合 "11.22*.*.*:允许,11.22.33.0-31:拒绝某部门登录,11.22.33.0/24:拒绝,#/INC/IP001.TXT:允许"
' 容错 "11.22*.*.* :::允许 , , , 11.22.33-34.0-31:拒绝优先允许 , 无, ,#IP001.TXT:允许 , , "
'返回值: true/false 即允许或拒绝登录
'说明:给定范围为空则全部允许,未指明允许或拒绝则全部拒绝。
'************************************************************
Public Function CheckIp(cInput_Ip,cBound_Ip)
dim cSingle_Ip,cTemp_IP,cStart_IP,cEnd_Ip,cIp4,cSubnet_CIDR,Subnet,Start_IP,End_Ip,status,IPFileName,ipline
CheckIp = false
cBound_Ip= Replace(cBound_Ip," ","") '去除半角空格,防止*的左边包含空格,影响对比。
cBound_Ip= Replace(cBound_Ip," ","") '去除全角空格
cBound_Ip= Replace(cBound_Ip," ","")
cBound_Ip= Replace(cBound_Ip,",",",") '改逗号,为,
cBound_Ip= Replace(cBound_Ip,":",":") '改冒号:为:
cBound_Ip= Replace(cBound_Ip,"-","-") '改减号-为-
cBound_Ip= Replace(cBound_Ip,"*","*") '改星号*为*
cBound_Ip= Replace(cBound_Ip,"~","~") '改~为~
cBound_Ip= Replace(cBound_Ip,"/","/") '改/为/
cBound_Ip= Replace(cBound_Ip,"#","#") '改#为#
cBound_Ip= Replace(cBound_Ip,"<br>",",") '处理换行符
cBound_Ip= Replace(cBound_Ip,"<br />",",")
cBound_Ip= Replace(cBound_Ip,"<br/>",",")
cBound_Ip= Replace(cBound_Ip,"<p>",",")
cBound_Ip= Replace(cBound_Ip,"</p>",",")
cBound_Ip= Replace(cBound_Ip,chr(10),",")
cBound_Ip= Replace(cBound_Ip,chr(13),",")
cBound_Ip= Replace(cBound_Ip,vbCrLf,",")
cBound_Ip= Replace(cBound_Ip,vbCr,",")
cBound_Ip= Replace(cBound_Ip,vbLf,",")
cBound_Ip= Replace(cBound_Ip,"ALLOW","允许") '改字符ALLOW为允许,以便兼容旧版本。
cBound_Ip= Replace(cBound_Ip,"REFUSE","拒绝") '改字符REFUSE为拒绝,以便兼容旧版本。
cBound_Ip= Replace(cBound_Ip,";",",") '改分号;为逗号,显示更加清晰,同时兼容旧版本。
if cBound_Ip="" or isnull(cBound_Ip) then '全部允许
CheckIp = true
exit function
end if
if Instr(cBound_Ip,"拒绝")=0 and Instr(cBound_Ip,"允许")=0 then '全部拒绝
CheckIp = false
exit function
end if
cSingle_Ip=split(cBound_Ip,",") '多个范围以逗号,循环
for i=0 to ubound(cSingle_Ip)
status="无"
if Instr(cSingle_Ip(i),"允许") <> 0 then status="允许"
if Instr(cSingle_Ip(i),"拒绝") <> 0 then status="拒绝"
if status<>"无" then cTemp_IP = left(cSingle_Ip(i),instr (cSingle_Ip(i),":")-1)
'if status<>"无" then cTemp_IP = left(cSingle_Ip(i),InStrRev (cSingle_Ip(i),":")-1) '#方式不必考虑绝对路径d:/dir
if Instr(cTemp_IP,"*") <> 0 then '是宽范围*
cStart_IP = left(cTemp_IP,instr(cTemp_IP,"*")-1)
if left(cInput_Ip,len(cStart_IP))=cStart_IP then
if status="拒绝" then CheckIp = false
if status="允许" then CheckIp = true
Response.Write "演示结果:宽范围"& cStart_IP & "*:" & status & "<BR>"
end if
end if
if Instr(cTemp_IP,"-") = 0 then '区间-的处理
cStart_IP = cTemp_IP '是单个IP
cEnd_Ip = cTemp_IP
else
cIp4=split(cTemp_IP,".") '共4节
if Instr(cIp4(3),"-") <> 0 then
cStart_IP = cIp4(0)+"."+cIp4(1)+"."+cIp4(2)+"."+ left(cIp4(3),instr(cIp4(3),"-")-1)
cEnd_Ip = cIp4(0)+"."+cIp4(1)+"."+cIp4(2)+"."+ mid(cIp4(3),instr(cIp4(3),"-")+1)
end if
if Instr(cIp4(2),"-") <> 0 then
cStart_IP = cIp4(0)+"."+cIp4(1)+"."+ left(cIp4(2),instr(cIp4(2),"-")-1) +".0"
cEnd_Ip = cIp4(0)+"."+cIp4(1)+"."+ mid(cIp4(2),instr(cIp4(2),"-")+1) +".255"
end if
if Instr(cIp4(1),"-") <> 0 then
cStart_IP = cIp4(0)+"."+ left(cIp4(1),instr(cIp4(1),"-")-1) +".0.0"
cEnd_Ip = cIp4(0)+"."+ mid(cIp4(1),instr(cIp4(1),"-")+1) +".255.255"
end if
if Instr(cIp4(0),"-") <> 0 then
cStart_IP = left(cIp4(0),instr(cIp4(0),"-")-1) +".0.0.0"
cEnd_Ip = mid(cIp4(0),instr(cIp4(0),"-")+1) +".255.255.255"
end if
end if
if Instr(cTemp_IP,"~") <> 0 then '之间~的处理
cStart_IP = left(cTemp_IP,instr(cTemp_IP ,"~")-1)
cEnd_Ip = mid(cTemp_IP,instr(cTemp_IP,"~")+1)
end if
if Instr(cTemp_IP,"#") <> 0 then '#处理IP限制库文件,例如 #/virtualdir/ip001.txt
IPFileName=mid(cTemp_IP,instr(cTemp_IP,"#")+1)
set fso=server.createobject("scripting.filesystemobject")
set file=fso.OpenTextFile(server.mappath(IPFileName),1,true)
cStart_IP ="127.0.0.1" '防止ip.txt全空或无记录时出错
cEnd_Ip ="127.0.0.1"
do while not file.AtEndOfStream
ipline=file.readline
if Instr(ipline,"~") <> 0 then
cStart_IP = left(ipline,instr(ipline ,"~")-1)
cEnd_Ip = mid(ipline,instr(ipline,"~")+1)
end if
if Ip2Str(cInput_Ip)>=Ip2Str(cStart_IP) and Ip2Str(cInput_Ip)<=Ip2Str(cEnd_Ip) then
exit do
end if
loop
file.close
set file=nothing
set fso=nothing
end if
if Instr(cTemp_IP,"/")<> 0 and Instr(cTemp_IP,"#")=0 then '/子网掩码和位数CIDR的处理,排除#/ip001.txt含/
cStart_IP = left(cTemp_IP,instr(cTemp_IP ,"/")-1)
cSubnet_CIDR = mid(cTemp_IP,instr(cTemp_IP,"/")+1)
if len(cSubnet_CIDR &"")<4 then
Subnet =2^32-2^(32-cint(cSubnet_CIDR))
else
Subnet= Ip2Str(cSubnet_CIDR)
end if
Start_IP=And2( Ip2Str(cStart_IP),Subnet ) '网段的开始地址(子网地址) = 主机地址 AND 子网掩码
End_Ip= Start_IP + Ip2Str("255.255.255.255")-Subnet '网段的结束地址(广播地址) = 网段的开始地址(子网地址)+通配符掩码("255.255.255.255"- 子网掩码)
cStart_IP = Str2Ip(Start_IP)
cEnd_Ip = Str2Ip(End_Ip)
end if
if Ip2Str(cInput_Ip)>=Ip2Str(cStart_IP) and Ip2Str(cInput_Ip)<=Ip2Str(cEnd_Ip) then
if status="拒绝" then CheckIp = false
if status="允许" then CheckIp = true
Response.Write "演示结果:开始"& Str2Ip(Ip2Str(cStart_IP))& " 结束" & Str2Ip(Ip2Str(cEnd_Ip)) & ":" & status &"<BR>"
end if
next
end function
'******************************
'Function Ip2Str(cIp)
'Created by qqdao, qqdao@263.net 2001/11/28
'参考动网ip算法
'参数:cIp ip地址
'返回值: 转换后数值
Public Function Ip2Str(cIp)
Dim str1,str2,str3,str4
Dim cIp_Temp
if cIp="127.0.0.1" then cIp="192.168.0.1"
str1=left(cIp,instr(cIp,".")-1)
cIp_Temp=mid(cIp,instr(cIp,".")+1)
str2=left(cIp_Temp,instr(cIp_Temp,".")-1)
cIp_Temp=mid(cIp_Temp,instr(cIp_Temp,".")+1)
str3=left(cIp_Temp,instr(cIp_Temp,".")-1)
str4=mid(cIp_Temp,instr(cIp_Temp,".")+1)
if isNumeric(str1)=0 or isNumeric(str2)=0 or isNumeric(str3)=0 or isNumeric(str4)=0 then
'
else
Ip2Str=cint(str1)*256*256*256+cint(str2)*256*256+cint(str3)*256+cint(str4) '不应当再减1
end if
end function
'******************************
'大整数逻辑与(AND)运算,参考CSDN论坛hookee和mocom资料
Public Function And2(ByVal A, ByVal B)
'and2=( (A/65536) and (B/65536) ) *65536 + ( (A mod 65536) and (B mod 65536) ) '使用/ 或 mod 就溢出
and2=( INT(A/65536) and INT(B/65536) )*65536+((A-int(A/65536) * 65536) and (B-int(B/65536)*65536) )
'Response.Write And2(185999660, 4294965248) &"(结果是185999360)<br>"
'Response.Write And2(99775533113355,123456789) &"(结果是85016577)<br>"
End Function
'********************************
Public Function Str2Ip(ByVal IP)
Dim str(3)
str(0)=INT(IP/256/256/256)
str(1)=INT( (IP-str(0)*256*256*256) /256/256 )
str(2)=INT( (ip-str(0)*256*256*256-str(1)*256*256)/256 )
str(3)=INT( ip-str(0)*256*256*256-str(1)*256*256-str(2)*256 +.1)
Str2Ip= Join( str,"." )
End Function
'Response.Write Str2Ip(185999660) &"(结果是11.22.33.44)<br>"
'********************************
Public Function getIP()
Dim strIPAddr,strHXFF
strHXFF=Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If strHXFF = "" OR InStr(strHXFF,"unknown")>0 Then
strIPAddr = Request.ServerVariables("REMOTE_ADDR")
ElseIf InStr(strHXFF, ",") > 0 Then
strIPAddr = Mid(strHXFF, 1, InStr(strHXFF, ",")-1)
ElseIf InStr(strHXFF, ";") > 0 Then
strIPAddr = Mid(strHXFF, 1, InStr(strHXFF, ";")-1)
Else
strIPAddr = strHXFF
End If
getIP = Trim(Mid(strIPAddr, 1, 30))
End Function
'Response.Write getIP()
'********************************
%>