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

ASP
一个ASP版的图片浏览管理器
无组件上传图片至SQLSERVER数据库
利用Jmail.Message发送邮件
用Web页面执行客户端程序
多图片上传到指定的目录并存到数据库
dreamweaverMX通用分页代码研究
下拉菜单输入,根据输入内容自动定位
中文的无组件文件上传ASP函数
一个利用adsi得到局域网信息的asp文件
根据需要动态include不同的文件
让自定义文件下载支持断点续传
用数组实现数据记录的批量录入方法
上传的进度条 实时反映上传情况
用ASP动态生成javascript的表单验证代码
ASP 编程中20个非常有用的例子
ASP生成Word文档的又一方法
用asp解析图片地址,并将其保存。
利用ASP的文件操作实现用户管理
创建 Visual Basic COM 组件在 ASP 中使用
调试 ASP 中使用的 Visual Basic COM 组件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-22   浏览: 155 ::
收藏到网摘: 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