电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

判断IP的来源是电信还是网通


发布日期:2018/11/13
 

不多废话直接开始说一种超快的算法吧既然要极快莫过于o()的复杂度所以开辟一巨大的缓沖区用经典的空间换时间通过查表一步即可判定那如何定义表的大小还有key?先从cnctxt这个文件看起

这个文件是中国网通的路由表仔细观察下不难发现掩码位数最高不超过(即)事实上位的掩码是非常至少毕竟一个网通的网段里只划分了个ip已是相当的少了既然掩码位数最多只有所以ip的最后一位可以忽略不计而ip的前位共有^(=m)的组合所以将ip的前位作为keym的表长度正好定义出ip对应网段的表可以形象如下表示:

/ => table[] = true

/ => table[] = true

table[] = true

table[] = true

检测的时候取ip前检测表中对应是否为true即可判断出此ip的类型事实上本例中ip只有电信和网通两种状态(非网通网段都当作电信)因此只需bit即可保存每个记录这时表占用的内存只需m/=m下面就用asp教程来实现这功能

首先将路由表转化成一个m大小的缓存表考虑到asp的运行速度这里事先用c程序直接处理然后保存为一个m的二进制文件asp通过adbdostream读取数据流并缓存在appliction集合中所谓的数据流其实也就是个byte()变量可以通过midbascb这类二进制函数来处理

初始化函数:

sub init()

if lenb(application("cnc")) then

exit sub

end if

with servercreateobject("adodbstream")

type =

open

loadfromfile servermappath("cncdat")

application("cnc") = read

close

end with

end sub

通过appliction集合的缓存就不必每次都读取文件m大小的内存也是可以接受的接着就是分析ip地址将其前位转换成一个数字因为这里每个记录是按位(bit)保存的所以还要整除来对应到byte()的位置最后通过mod运算对应到具体字节的具体bit上听着有些复杂不过实现起来确是相当的简单:

function ipiscnc(ip)

dim arr val

dim c

arr = split(ip "")

val = clng(arr()) * + clng(arr()) * + clng(arr())

c = ascb(midb(application("cnc") val + ))

ipiscnc = _

(c and ^(val mod )) <>

end function

ipiscnc(ip)返回ip地址是否为网通

到此关键的两个函数就大功告成了接着测试:

sub main()

on error resume next

init()

if err then

responsewrite "系统错误: " & errdescription

exit sub

end if

dim ip

ip = requestservervariables("remote_addr")

if ipiscnc(ip) then

responsewrite ip & "属于网通ip"

else

responsewrite ip & "属于电信ip"

end if

end sub

main()

考虑到init函数需要文件的读取所以添加了错误捕捉不过通常情况下ipiscnc是不会错误的因为remote_addr返回的必然是个正确格式的ip

每当访问asp时除了第一次需加载文件外其余时候只需三四行代码既可以判定真正实现了空间换时间

上一篇:网页跳转代码简介

下一篇:计算页面执行时间