推荐.NET教程: ASP.NET C# 开发环境 Ajax教程 控件开发 统计报表 数据库 Web服务 安装部署 CommunityServer NHibernate DataGrid/GridView 实用代码 VS2005
示例源码 MVC/三层 SqlHelper 入门源码 开源 CMS Ajax/Atlas C#.net 毕业设计 源码 经典代码 商业 本站作品 持久层 随书源码 WebService 英文/汉化 Asp.net2.0

阿牛·乐园

每天进步一点点

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  80 随笔 :: 14 文章 :: 389 评论 :: 13 引用
编程语言:C#
类    别:(网络应用,实用算法)
主要功能:查询一个IP所有的IP段.
关键:从Byte数组到ulong的转换出来的数字和 IPAddress.Address 返回值的是不一样的.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;

namespace IPUtility
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            IPRangeManage irm 
= new IPRangeManage();
            irm.Add(
new IPRange("石家庄""219.148.24.0""219.148.63.255"));
            irm.Add(
new IPRange("石家庄""222.222.0.0""222.222.63.255"));
            irm.Add(
new IPRange("唐山""219.148.64.0""219.148.79.255"));
            irm.Add(
new IPRange("保定""219.148.20.0""219.148.23.255"));

            Console.WriteLine(irm.Search(
"219.148.56.3").Name);

            Console.ReadLine();

        }



    }


    
public class IPRange 
    
{
        
private string _Name = string.Empty;

        
private ulong _BeginIP = 0;

        
private ulong _EndIP = Int32.MaxValue;

        
/// <summary>
        
/// IP段名称
        
/// </summary>

        public string Name
        
{
            
get return _Name; }
            
set { _Name = value; }
        }


        
/// <summary>
        
/// 开始IP
        
/// </summary>

        public ulong BeginIP
        
{
            
get return _BeginIP; }
            
set { _BeginIP = value; }
        }


        
/// <summary>
        
/// 结束IP
        
/// </summary>

        public ulong EndIP
        
{
            
get return _EndIP; }
            
set { _EndIP = value; }
        }



        
/// <summary>
        
/// 此IP段的范围
        
/// </summary>

        public ulong Range
        
{
            
get
            
{
                
return EndIP - BeginIP;
            }

        }


        
public IPRange(string name, string ipBegin, string ipEnd)
        
{
            
this.Name = name;
            
this.BeginIP = IP2A(ipBegin);
            
this.EndIP = IP2A(ipEnd);
        }



        
public static ulong IP2A(string ip)
        
{
            
byte[] bytes = IPAddress.Parse(ip).GetAddressBytes();
            
ulong ret = 0;

            
foreach (byte b in bytes)
            
{
                ret 
<<= 8;
                ret 
|= b;
            }


            
return ret;

        }



        
public static int Compare(IPRange x, IPRange y)
        
{
            
if(x.Range == y.Range)
                
return 0;
            
else if(x.Range > y.Range)
                
return 1;
            
else return -1;
        }


    }


    
public class IPRangeManage
    
{
        
public IPRangeManage()
        
{ }

        
private List< IPRange> _IPRangeList = new List< IPRange>();
        
private bool _NeedSort = true;

        
public void Add(IPRange ipRange)
        
{
            _IPRangeList.Add(ipRange);
            _NeedSort 
= true;
        }


        
private void Sort()
        
{
            
if (_NeedSort)
            
{
                _IPRangeList.Sort(
new Comparison<IPRange>(IPRange.Compare));
            }

        }


        
public IPRange Search(string ipString)
        
{
            
ulong ip = IPRange.IP2A(ipString);

            
this.Sort();

            
foreach (IPRange ir in _IPRangeList)
            
{
                
if (ir.BeginIP <= ip && ir.EndIP >= ip)
                
{
                    
return ir;
                }

            }


            
return null;
        }



    }





}


posted on 2007-05-18 23:06 阿牛 阅读(2171) 评论(10)  编辑 收藏 网摘

评论

#1楼  2007-05-19 00:24 刚刚      
不错的东东
  回复  引用  查看    

#2楼  2007-05-19 01:36 Cat Chen      
IP就是设计为可以按byte来&运算的,所以保存IP范围的数据结构应该是IP加上Mask。而你现在把IP当做整数来进行大小比较运算以决定是否在范围之内,其实效率已经低了。
  回复  引用  查看    

#3楼  2007-05-19 09:03 overred      
不错
如果只想判断ip归属地
可以使用qq的QQwry.dat,而且随时可以更新

  回复  引用  查看    

#4楼  2007-05-19 10:43 51aspx.com      
阿牛写的 一定要收藏
  回复  引用  查看    

#5楼  2007-05-19 13:08 o摆摆o0O       
免费提供IP城市数据库下载
http://www.sonrun.com
演示地址:http://www.sonrun.com/demo/ip

绝非广告!
  回复  引用  查看    

无聊,走到此处,有新内容了,不错,加油!
  回复  引用    

#7楼 [楼主] 2007-05-21 17:37 阿牛      
@Cat Chen
同意你的观点,但如果客户给的是IP段,没有MASK,或者不能通过MASK来准确的标示一个范围.这时,这小段代码就有用了.

因为只要分出是哪个地市就可以了?数据量小,效率几乎可以乎略.但我想总比字串来比较高一点吧.

哈哈.共同进步

  回复  引用  查看    

#8楼 [楼主] 2007-05-21 17:40 阿牛      
这段代码还有一个用处,用于没有限制交集,所以对于用IP段来控制访问的时候,我们可以先指定大范围,然后指定小范围来指出特别的区段.

如果实现 0.0.0.0 - 255.255.255.255 都可以访问
但 1.0.0.0 - 2.0.0.0 不可以访问.

  回复  引用  查看    

ret <<= 8;
ret |= b;

这里干嘛要这样呢?请楼主指点

loveme821102@126.com

  回复  引用    

#10楼 [楼主] 2008-05-13 13:18 阿牛      
@loveme告诉我吧
这个意思是 ret = ret * 2^8 然后 ret = ret + b

这样写,效率要高一点.
  回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
Google站内搜索

China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!
开发者征途系统新作:《设计模式——基于C#的工程化实现及扩展》



相关文章:

相关链接: