输入一个IP地址, 在上千条IP地址范围内查找 该IP地址的是属于那个IP地址范围?

superdreamer 2007-06-26 05:28:41
呵呵, 标题有点让人看不明白, 现在举例如下:
IP地址范围如下:
60.12.0.0-60.12.0.255
202.96.0.0-202.96.128.90
..................
..................
..................
222.12.0.0-222.12.0.255

类似上面的IP地址范围, 但总共的条数有上千条
现在假如输入一个IP地址: 202.96.0.12查找该IP地址属于那个IP地址范围. 按上面的数据应该返回202.96.0.0-202.96.128.90这条记录.

最简单的方法是将IP地址转化为unsigned int的, 然后排序查找, 但这样效率很低, 那位大哥有好的方法, 请指教, 谢谢!
...全文
974 25 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
shdongsichyang 2008-08-02
  • 打赏
  • 举报
回复
要考虑区间重叠问题,算法导论上有道例题用树做的,好像是关于线段的。
按区间首地址排序即可,查找比给出值key小的首地址,若比尾地址大直接返回成功;否则继续匹配下一个区间
lovebanyi 2007-06-29
  • 打赏
  • 举报
回复
不是单单的排序啊.要进行二分法的.还好.不会很慢
superdreamer 2007-06-29
  • 打赏
  • 举报
回复
to--->tailzhou(尾巴)
再次感谢你的热心回复.
在同一时间大约有100-200台电脑, 也很有可能有大量的重复的IP地址. 但用HASH来缓冲IP的话, 也需要查找几次, 我现在的做法是先根据IP地址的前2个byte来做HASH数据的下标, 然后在排序查找. 这样需要占有100k左右的内存, 这样再查找应该能节省很多时间,还有一个另外的因素, 有可能有很多IP地址不在我收集的IP地址范围内, 这样查找的话, 只需要一次比较和一个copy的指令时间.
cuixiping 2007-06-29
  • 打赏
  • 举报
回复
化成整数了,然后按顺序排好。查的时候就用2分法。
tailzhou 2007-06-28
  • 打赏
  • 举报
回复
还有,你的机器同一时间大约接收多少台机器的数据?

同一时间段内,是否有大量的重复的ip传输过来的包?

可以考虑用hash来缓存最近的一定数量的ip所对应的子网;
tailzhou 2007-06-28
  • 打赏
  • 举报
回复
排序后直接用二分查找,每次大约要10来次比较;

按你自己的方法来做,排序后对第一个byte做索引,平均需要1000/255,大约4次比较;

我觉得10来次比较不会怎么影响性能的吧?


acmilan1984 2007-06-28
  • 打赏
  • 举报
回复
IP1*255^3+IP2*255^2+IP3*255^1+IP4*255^0
然后查找即可。
tailzhou 2007-06-27
  • 打赏
  • 举报
回复
你的区间有没有重叠的?

如果没有重叠的,则,将起点与终点一起排序,用一个标志域来表示该数值是终点还是起点。

用二分查找完毕后,若前一个元素是起点且后一个是终点,则查找成功;
superdreamer 2007-06-27
  • 打赏
  • 举报
回复
==>to pi1ot(-=\Pilot/=-) (
我也想用这样的方法, 但不能用太大的内存, 因为我的系统总共内存只有32Mbyte, 你的方法能否具体点, 请见笑,我对算法研究不深. 还有效率肯定要比排序后查找要高才行.
用数据库是不太可能的, 我的系统是嵌入式,内存很小. 而且我希望速度要快.因为系统本身也支持查找, 不过是一条一条的轮循.
不管用那种方法,转化为网络字节序的32位的数据是必须的, 因为我输入的IP也是网络字节序的32位数字.
我现在也有点想法, 不过那算不上什么算法, 只能说针对我的系统的特定的东东罢了, 第一步还是取IP地址的第一个byte作为数组的下标, 这样就可以省去很多IP地址范围,接着在排序查找.
ahjoe 2007-06-27
  • 打赏
  • 举报
回复
转成int,排序当然也是必要的。
这样还会效率低?那就邪了。
不要告诉我,你每查一次都要转换并排序一次。
ahjoe 2007-06-27
  • 打赏
  • 举报
回复
要想最高效率,要把IP地址转成32bit数值。这么点儿数据,就不要用数据库了。
superdreamer 2007-06-27
  • 打赏
  • 举报
回复
排序在查找,是一个最简单的方法, 但我希望能更快的速度, 更少的指令就可以实现, 要知道我的CPU主频是只有166MHZ,最多的也不到600MHZ, 而且每一个数据包都要去比较, 要是比较次数太多, 每秒处理的数据包太多的话, 对系统的性能影响肯定还是比较大的,
ilovechao1314 2007-06-27
  • 打赏
  • 举报
回复
存到数据库中吧,
SoftBomb 2007-06-27
  • 打赏
  • 举报
回复
首先需要对地址范围进行组织,建议按IP地址分段做Hash映射表
然后一查就行了,感觉有点象那个键树
hthying 2007-06-27
  • 打赏
  • 举报
回复
晕,只要确定范围的话,将IP转化为整形不就行了。
60.12.0.0-60.12.0.255
二进制为:00111100。00001100。00000000。00000000-00111100。00001100。00000000。11111111
然后去掉。转成int形,
同理将输入一个IP地址: 202.96.0.12也转成int形
比较下大上,不就确定在哪个范围了?

yangb2014# 2007-06-27
  • 打赏
  • 举报
回复
适当排序,
yht201 2007-06-27
  • 打赏
  • 举报
回复
根本不属于查表的问题吧
shan_ghost 2007-06-27
  • 打赏
  • 举报
回复
另外,子网掩码还可以是:255.255.255.127等形式。根据自己的实际情况灵活运用。
shan_ghost 2007-06-27
  • 打赏
  • 举报
回复
比如:
60.12.0.0-60.12.0.255

子网掩码就是:
255.255.255.0

所在子网是:
60.12.0.0

把ip和子网掩码都转化为int,然后按位与(可以逐字节处理,如先和255.0.0.0与,提取第一字节;再和255.255.0.0,提取前二字节),就可以提取出所在子网号来;然后和有效子网逐个比对即可。

至于192.168.0.55~192.168.1.50这样跨子网的情形,则应把这个范围按子网分开存储,并设计一个数据结构,做个从子网号到IP再到实际范围的映射。
(即:从子网掩码找到子网,发现这个子网又被分为高低IP两个部分,于是找高或低IP部分,再找到与之相联系的范围定义)
shan_ghost 2007-06-27
  • 打赏
  • 举报
回复
子网掩码。。。
加载更多回复(5)

33,027

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧