导航

  1. 常用CHM
  2. 订阅
  • 本站大部分内容从网上收集,收集目的仅供研究、学习。涉及版权或不希望收录您的文章请您及时与我联系。
  • 本站IM群,请自行选择。请各位朋友按照自己喜好加入。加入群后请及时发言,防止被清理。谢谢您的合作!!!
  • QQ群:Y①WEB开发(ASP.NET)号码:7351660 QQ群:Y②WEB开发(ASP+.NET)号码:11864905
  • QQ群:Y③WEB开发(DIV+CSS)号码:16610506 QQ群:Y④WEB开发(JS+AJAX)号码:16143998
  • QQ群:Y⑤WEB开发(新手)号码:12777715 MSN群:yaosansi[at]126.com
« 你装QQ了没有?C#下用P2P技术实现点对点聊天 »

C#如何读取QQ纯真IP数据库

分类: C#|DOTNET 发布: yaosansi 浏览: 日期: 2005年11月10日

原文:http://www.yaosansi.com/post/278.html

使用方法:
例子:

Code Snippet
  1. BDQQ.Data.QQWry qq=new BDQQ.Data.QQWry("d:\\QQWry.Dat");
  2. BDQQ.Data.IPLocation ip=qq.SearchIPLocation("127.0.0.1");//这里添写IP地址
  3. Console.WriteLine(ip.country);//国家
  4. Console.WriteLine(ip.area);//地区

以下是类文件:
 

Code Snippet
  1. //根据LumaQQ改写而成.
  2.  
  3. using System;
  4. using System.IO;
  5. using System.Text;
  6.  
  7. namespace BDQQ.Data
  8. {
  9.     /**/
  10.     ///
  11.     /// QQWry 的摘要说明。
  12.     ///
  13.     public class QQWry
  14.     {
  15.         //第一种模式
  16.         #region 第一种模式
  17.         /**/
  18.         ///
  19.         /// 第一种模式
  20.         ///
  21.         #endregion
  22.         private const byte REDIRECT_MODE_1 = 0x01;
  23.  
  24.         //第二种模式
  25.         #region 第二种模式
  26.         /**/
  27.         ///
  28.         /// 第二种模式
  29.         ///
  30.         #endregion
  31.         private const byte REDIRECT_MODE_2 = 0x02;
  32.  
  33.         //每条记录长度
  34.         #region 每条记录长度
  35.         /**/
  36.         ///
  37.         /// 每条记录长度
  38.         ///
  39.         #endregion
  40.         private const int IP_RECORD_LENGTH = 7;
  41.  
  42.         //数据库文件
  43.         #region 数据库文件
  44.         /**/
  45.         ///
  46.         /// 文件对象
  47.         ///
  48.         #endregion
  49.         private FileStream ipFile;
  50.  
  51.         private const string unCountry = "未知国家";
  52.         private const string unArea = "未知地区";
  53.  
  54.         //索引开始位置
  55.         #region 索引开始位置
  56.         /**/
  57.         ///
  58.         /// 索引开始位置
  59.         ///
  60.         #endregion
  61.         private long ipBegin;
  62.  
  63.         //索引结束位置
  64.         #region 索引结束位置
  65.         /**/
  66.         ///
  67.         /// 索引结束位置
  68.         ///
  69.         #endregion
  70.         private long ipEnd;
  71.  
  72.         //IP地址对象
  73.         #region IP地址对象
  74.         /**/
  75.         ///
  76.         /// IP对象
  77.         ///
  78.         #endregion
  79.         private IPLocation loc;
  80.  
  81.         //存储文本内容
  82.         #region 存储文本内容
  83.         /**/
  84.         ///
  85.         /// 存储文本内容
  86.         ///
  87.         #endregion
  88.         private byte[] buf;
  89.  
  90.         //存储3字节
  91.         #region 存储3字节
  92.         /**/
  93.         ///
  94.         /// 存储3字节
  95.         ///
  96.         #endregion
  97.         private byte[] b3;
  98.  
  99.         //存储4字节
  100.         #region 存储4字节
  101.         /**/
  102.         ///
  103.         /// 存储4字节IP地址
  104.         ///
  105.         #endregion
  106.         private byte[] b4;
  107.  
  108.         //构造函数
  109.         #region 构造函数
  110.         /**/
  111.         ///
  112.         /// 构造函数
  113.         ///
  114.         /// IP数据库文件绝对路径 #endregion
  115.         public QQWry(string ipfile)
  116.         {
  117.  
  118.             buf = new byte[100];
  119.             b3 = new byte[3];
  120.             b4 = new byte[4];
  121.             try
  122.             {
  123.                 ipFile = new FileStream(ipfile, FileMode.Open);
  124.             }
  125.             catch (Exception ex)
  126.             {
  127.                 throw new Exception(ex.Message);
  128.             }
  129.             ipBegin = readLong4(0);
  130.             ipEnd = readLong4(4);
  131.             loc = new IPLocation();
  132.         }
  133.  
  134.  
  135.         //根据IP地址搜索
  136.         #region 根据IP地址搜索
  137.         /**/
  138.         ///
  139.         /// 搜索IP地址搜索
  140.         ///
  141.         /// ///
  142.         #endregion
  143.         public IPLocation SearchIPLocation(string ip)
  144.         {
  145.             //将字符IP转换为字节
  146.             string[] ipSp = ip.Split('.');
  147.             if (ipSp.Length != 4)
  148.             {
  149.                 throw new ArgumentOutOfRangeException("不是合法的IP地址!");
  150.             }
  151.             byte[] IP = new byte[4];
  152.             for (int i = 0; i < IP.Length; i++)
  153.             {
  154.                 IP[i] = (byte)(Int32.Parse(ipSp[i]) & 0xFF);
  155.             }
  156.  
  157.             IPLocation local = null;
  158.             long offset = locateIP(IP);
  159.  
  160.             if (offset != -1)
  161.             {
  162.                 local = getIPLocation(offset);
  163.             }
  164.  
  165.             if (local == null)
  166.             {
  167.                 local = new IPLocation();
  168.                 local.area = unArea;
  169.                 local.country = unCountry;
  170.             }
  171.             return local;
  172.         }
  173.  
  174.  
  175.         //取得具体信息
  176.         #region 取得具体信息
  177.         /**/
  178.         ///
  179.         /// 取得具体信息
  180.         ///
  181.         /// ///
  182.         #endregion
  183.         private IPLocation getIPLocation(long offset)
  184.         {
  185.             ipFile.Position = offset + 4;
  186.             //读取第一个字节判断是否是标志字节
  187.             byte one = (byte)ipFile.ReadByte();
  188.             if (one == REDIRECT_MODE_1)
  189.             {
  190.                 //第一种模式
  191.                 //读取国家偏移
  192.                 long countryOffset = readLong3();
  193.                 //转至偏移处
  194.                 ipFile.Position = countryOffset;
  195.                 //再次检查标志字节
  196.                 byte b = (byte)ipFile.ReadByte();
  197.                 if (b == REDIRECT_MODE_2)
  198.                 {
  199.                     loc.country = readString(readLong3());
  200.                     ipFile.Position = countryOffset + 4;
  201.                 }
  202.                 else
  203.                     loc.country = readString(countryOffset);
  204.  
  205.                 //读取地区标志
  206.                 loc.area = readArea(ipFile.Position);
  207.  
  208.             }
  209.             else if (one == REDIRECT_MODE_2)
  210.             {
  211.                 //第二种模式
  212.                 loc.country = readString(readLong3());
  213.                 loc.area = readArea(offset + 8);
  214.             }
  215.             else
  216.             {
  217.                 //普通模式
  218.                 loc.country = readString(--ipFile.Position);
  219.                 loc.area = readString(ipFile.Position);
  220.             }
  221.             return loc;
  222.         }
  223.  
  224.  
  225.         //取得地区信息
  226.         #region 取得地区信息
  227.         /**/
  228.         ///
  229.         /// 读取地区名称
  230.         ///
  231.         /// ///
  232.         #endregion
  233.         private string readArea(long offset)
  234.         {
  235.             ipFile.Position = offset;
  236.             byte one = (byte)ipFile.ReadByte();
  237.             if (one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2)
  238.             {
  239.                 long areaOffset = readLong3(offset + 1);
  240.                 if (areaOffset == 0)
  241.                     return unArea;
  242.                 else
  243.                 {
  244.                     return readString(areaOffset);
  245.                 }
  246.             }
  247.             else
  248.             {
  249.                 return readString(offset);
  250.             }
  251.         }
  252.  
  253.  
  254.         //读取字符串
  255.         #region 读取字符串
  256.         /**/
  257.         ///
  258.         /// 读取字符串
  259.         ///
  260.         /// ///
  261.         #endregion
  262.         private string readString(long offset)
  263.         {
  264.             ipFile.Position = offset;
  265.             int i = 0;
  266.             for (i = 0, buf[i] = (byte)ipFile.ReadByte(); buf[i] != (byte)(0); buf[++i] = (byte)ipFile.ReadByte()) ;
  267.  
  268.             if (i > 0)
  269.                 return Encoding.Default.GetString(buf, 0, i);
  270.             else
  271.                 return "";
  272.         }
  273.  
  274.  
  275.         //查找IP地址所在的绝对偏移量
  276.         #region 查找IP地址所在的绝对偏移量
  277.         /**/
  278.         ///
  279.         /// 查找IP地址所在的绝对偏移量
  280.         ///
  281.         /// ///
  282.         #endregion
  283.         private long locateIP(byte[] ip)
  284.         {
  285.         long m = 0;
  286.         int r;
  287.  
  288.         //比较第一个IP项
  289.         readIP( ipBegin, b4 );
  290.         r = compareIP( ip,b4);
  291.         if( r == 0 )
  292.         return ipBegin;
  293.         else if( r < 0 )
  294.         return -1;
  295.         //开始二分搜索
  296.         for( long i = ipBegin,j=ipEnd; i {
  297.         m = this.getMiddleOffset( i,j );
  298.         readIP( m,b4 );
  299.         r = compareIP( ip,b4 );
  300.         if( r > 0 )
  301.         i = m;
  302.         else if( r < 0 )
  303.         {
  304.         if( m == j )
  305.         {
  306.         j -= IP_RECORD_LENGTH;
  307.         m = j;
  308.         }
  309.         else
  310.         {
  311.         j = m;
  312.         }
  313.         }
  314.         else
  315.         return readLong3( m+4 );
  316.         }
  317.         m = readLong3( m+4 );
  318.         readIP( m,b4 );
  319.         r = compareIP( ip,b4 );
  320.         if( r <= 0 )
  321.         return m;
  322.         else
  323.         return -1;
  324.         }
  325.  
  326.  
  327.         //读出4字节的IP地址
  328.         #region 读出4字节的IP地址
  329.         /**/
  330.         ///
  331.         /// 从当前位置读取四字节,此四字节是IP地址
  332.         ///
  333.         /// /// #endregion
  334.         private void readIP(long offset, byte[] ip)
  335.         {
  336.             ipFile.Position = offset;
  337.             ipFile.Read(ip, 0, ip.Length);
  338.             byte tmp = ip[0];
  339.             ip[0] = ip[3];
  340.             ip[3] = tmp;
  341.             tmp = ip[1];
  342.             ip[1] = ip[2];
  343.             ip[2] = tmp;
  344.         }
  345.  
  346.  
  347.         //比较IP地址是否相同
  348.         #region 比较IP地址是否相同
  349.         /**/
  350.         ///
  351.         /// 比较IP地址是否相同
  352.         ///
  353.         /// /// /// 0:相等,1:ip大于beginIP,-1:小于
  354.         #endregion
  355.         private int compareIP(byte[] ip, byte[] beginIP)
  356.         {
  357.             for (int i = 0; i < 4; i++)
  358.             {
  359.                 int r = compareByte(ip[i], beginIP[i]);
  360.                 if (r != 0)
  361.                     return r;
  362.             }
  363.             return 0;
  364.         }
  365.  
  366.  
  367.         //比较两个字节是否相等
  368.         #region 比较两个字节是否相等
  369.         /**/
  370.         ///
  371.         /// 比较两个字节是否相等
  372.         ///
  373.         /// /// ///
  374.         #endregion
  375.         private int compareByte(byte bsrc, byte bdst)
  376.         {
  377.             if ((bsrc & 0xFF) > (bdst & 0xFF))
  378.                 return 1;
  379.             else if ((bsrc ^ bdst) == 0)
  380.                 return 0;
  381.             else
  382.                 return -1;
  383.         }
  384.  
  385.  
  386.         //根据当前位置读取4字节
  387.         #region 根据当前位置读取4字节
  388.         /**/
  389.         ///
  390.         /// 从当前位置读取4字节,转换为长整型
  391.         ///
  392.         /// ///
  393.         #endregion
  394.         private long readLong4(long offset)
  395.         {
  396.             long ret = 0;
  397.             ipFile.Position = offset;
  398.             ret |= (ipFile.ReadByte() & 0xFF);
  399.             ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
  400.             ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
  401.             ret |= ((ipFile.ReadByte() << 24) & 0xFF000000);
  402.             return ret;
  403.         }
  404.  
  405.  
  406.         //根据当前位置,读取3字节
  407.         #region 根据当前位置,读取3字节
  408.         /**/
  409.         ///
  410.         /// 根据当前位置,读取3字节
  411.         ///
  412.         /// ///
  413.         #endregion
  414.         private long readLong3(long offset)
  415.         {
  416.             long ret = 0;
  417.             ipFile.Position = offset;
  418.             ret |= (ipFile.ReadByte() & 0xFF);
  419.             ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
  420.             ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
  421.             return ret;
  422.         }
  423.  
  424.  
  425.         //从当前位置读取3字节
  426.         #region 从当前位置读取3字节
  427.         /**/
  428.         ///
  429.         /// 从当前位置读取3字节
  430.         ///
  431.         ///
  432.         #endregion
  433.         private long readLong3()
  434.         {
  435.             long ret = 0;
  436.             ret |= (ipFile.ReadByte() & 0xFF);
  437.             ret |= ((ipFile.ReadByte() << 8) & 0xFF00);
  438.             ret |= ((ipFile.ReadByte() << 16) & 0xFF0000);
  439.             return ret;
  440.         }
  441.  
  442.  
  443.         //取得begin和end之间的偏移量
  444.         #region 取得begin和end之间的偏移量
  445.         /**/
  446.         ///
  447.         /// 取得begin和end中间的偏移
  448.         ///
  449.         /// /// ///
  450.         #endregion
  451.         private long getMiddleOffset(long begin, long end)
  452.         {
  453.             long records = (end - begin) / IP_RECORD_LENGTH;
  454.             records >>= 1;
  455.             if (records == 0)
  456.                 records = 1;
  457.             return begin + records * IP_RECORD_LENGTH;
  458.         }
  459.     } //class QQWry
  460.  
  461.     public class IPLocation
  462.     {
  463.         public String country;
  464.         public String area;
  465.  
  466.         public IPLocation()
  467.         {
  468.             country = area = "";
  469.         }
  470.  
  471.         public IPLocation getCopy()
  472.         {
  473.             IPLocation ret = new IPLocation();
  474.             ret.country = country;
  475.             ret.area = area;
  476.             return ret;
  477.         }
  478.     }
  479. }

相关文章:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

Powered By Z-Blog 1.8 Walle Build 100427

Copyright 2005-2010 yaosansi'site All Rights Reserved.
感谢系统大玩家为本站提供FTP空间
辽ICP备05021434号