当前位置: 首页 > 图文教程 > 网络编程 > ASP > 用asp判断某IP是否属于某网段的另类算法

ASP
ASP正则表达式技巧
ASP Access实现网站计数器(访问量)
ASP新闻分页,将一篇过长的文章分页,生成静态页面
一些关于asp 购物车的想法
一个sql查询器,自动画表格填字段
ASP实现文件直接下载的代码
把网页中的(电话,qq等数字)生成图片的ASP程序
asp长文章用分页符来分页显示
Asp函数介紹(37个常用函数)
ASP中的面向对象类
分页实现方法的性能比较
asp ajax跨域提交数据
asp修改文件和文件夹的名字的代码
ASP 多关键词查询实例代码
asp被杀毒软件误删的解决方法
asp 多关键词搜索的简单实现方法
asp 根据IP地址自动判断转向分站的代码
asp dictionary对象的用法
ASP 千万级数据分页的存储过程
ASP隐藏真实文件的下载功能实现代码

ASP 中的 用asp判断某IP是否属于某网段的另类算法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-22   浏览: 81 ::
收藏到网摘: n/a

有时候我们需要判断某一个IP地址是否属于一个网段,以决定该用户能否访问系统.
比如用户登录的IP是218.6.7.7,而我们的程序必须判断他是否属于218.6.0.0/16这个网段(其中/16是新的子网掩码的表示方式,相当于255.255.0.0).
要实现这样的功能,现在流行的算法是将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开头的,这将会造成数据溢出而出错。
其实比较IP是否属于某一网段,最好的方式就是将IP与网段分别转为32位二进制,再比较他们的网络部分是否相同就可以了.asp本身不具备位运行功能,所以要实现这个只有我们手工实现,具体如下:
'将十进制转为二进制字符串
function dec2bin(octNumber)
vara=octNumber
do
dec2bin=cstr(vara mod 2) & dec2bin
vara=vara \ 2
loop until vara=0
end function

'将二进制字符串填充为8位
function pad(str)
pad=right("00000000" & str,8)
end function

'判断是否是一个IP地址
function isIp(ipadd)
isIp=false
set oReg=new RegExp
oReg.IgnoreCase=true
oReg.global=true
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})"
if oReg.test(ipadd) then isIp=true
set oReg=nothing
end function

'其中UserIP是我们要检测的IP
'NetIP是要检测的网段或某个IP,用xxx.xxx.xxx.xxx/N来表示网段,其中N表示子网掩码位数
'注,该程序是环球万维原创程序,所以如果您要转载,请保留出处信息,谢谢.
'程序设计:环球万维,专业提供域名注册,虚拟主机服务
'网址:http://www.netInter.cn
'以上信息与文章正文是不可分割的一部分,所以如果您要转载本文章,您必须保留以上信息.

Function check_ip(UserIp,NetIP)
currentip=UserIp
collection_ips=split(iplist,",") '将网络按点分割成4段
check_ip=false '初始函数值,false假设IP不在这网段
NetIP=trim(NetIP)
slashPos=inStr(NetIP,"/")
if slashPos=0 then '网段没含有/符号,他只是一个IP,所以比较比个字符串是否相同就可以了
if NetIP=currentip then
check_ip=true 'check_ip=true表示IP相等
exit function
end if
else
netRang=mid(NetIP,slashPos+1) '得到/后边的数字
if not isNumeric(netRang) then '/后边不是数字,格式不正确
exit function
end if
netRang=cint(netRang) '将字符转为数字
if netRang>31 then
exit function '/后的数字不能超过32位
end if
ipsets=split(currentip,".") '将用户IP按点分成四段

C_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
'上边这行是将用户IP地址手工转换为对应的一个32个字符长的二进制
ipsets=split(NetIP,".") '按上边的过程将网段IP同样转为32个字符长的二进制
sPos=instr(ipsets(3),"/") '最后一点格式应该是 数字/数字
if sPos=0 then
exit function
end if
ipsets(3)=left(ipsets(3),sPos-1) '得到最后一段/前边的数字
S_IP_BIN=pad(dec2bin(ipsets(0))) & pad(dec2bin(ipsets(1))) & pad(dec2bin(ipsets(2))) & pad(dec2bin(ipsets(3)))
'将其转换为32个字符长的二进制
if left(C_IP_BIN,netRang) = left(S_IP_BIN,netRang) then '比较网段络是否相同就可以判断用户IP否属于某个网段了
check_ip=true
end if
end if
end function

应用举例:

要判断61.139.1.1是否在61.139.0.0/16 (255.255.0.0)这个网段
只需要简单的使用这个函数就可以了,如:

if check_ip("61.139.1.1","61.139.0.0/16") then
Response.write "同一网段"
else
Response.write "不是同一网段"
end if