用戶登錄  |  用戶注冊
首 頁源碼下載網絡學院最新源碼源碼排行屏蔽廣告
當前位置:新興網絡 > 網絡學院 > .Net技術 > C#

C# 讀取純真IP數據庫QQWry.dat獲取地區信息

減小字體 增大字體 作者:何道德  來源:本站整理  發布時間:2010-06-26 01:19:33
C# code復制代碼
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace 純真IP數據庫研究
{
    ///<summary>
    /// 提供從純真IP數據庫搜索IP信息的方法;
    /// 感謝LumaQQ提供純真IP數據庫格式文檔;
    /// ----HeDaode 2007-12-28 四川教育學院
    ///</summary>
    public class IPSearch
    {
        FileStream ipFile;
        long ip;
        string ipfilePath;

        ///<summary>
        /// 構造函數
        ///</summary>
        ///<param name="ipfilePath">純真IP數據庫路徑</param>
        public IPSearch(string ipfilePath)
        {
            this.ipfilePath = ipfilePath;
        }
        //測試
        static void Main(string[] args)
        {
            string ipfilePath = @"C:\Documents and Settings\Daode\桌面\qqwry\QQWry.dat";
            IPSearch ipSearch = new IPSearch(ipfilePath);
            string ip = "72.51.27.51";
            IPSearch.IPLocation loc = ipSearch.GetIPLocation(ip);
            Console.WriteLine("你查的ip是:{0} 地理位置:{1} {2}", ip, loc.country, loc.area);
            Console.ReadKey();
        }
        ///<summary>
        /// 地理位置,包括國家和地區
        ///</summary>
        public struct IPLocation
        {
            public string country, area;
        }
        ///<summary>
        /// 獲取指定IP所在地理位置
        ///</summary>
        ///<param name="strIP">要查詢的IP地址</param>
        ///<returns></returns>
        public IPLocation GetIPLocation(string strIP)
        {
            ip = IPToLong(strIP);
            ipFile = new FileStream(ipfilePath, FileMode.Open, FileAccess.Read);
            long[] ipArray = BlockToArray(ReadIPBlock());
            long offset = SearchIP(ipArray, 0, ipArray.Length - 1) * 7 + 4;
            ipFile.Position += offset;//跳過起始IP
            ipFile.Position = ReadLongX(3) + 4;//跳過結束IP

            IPLocation loc = new IPLocation();
            int flag = ipFile.ReadByte();//讀取標志
            if (flag == 1)//表示國家和地區被轉向
            {
                ipFile.Position = ReadLongX(3);
                flag = ipFile.ReadByte();//再讀標志
            }
            long countryOffset = ipFile.Position;
            loc.country = ReadString(flag);

            if (flag == 2)
            {
                ipFile.Position = countryOffset + 3;
            }
            flag = ipFile.ReadByte();
            loc.area = ReadString(flag);

            ipFile.Close();
            ipFile = null;
            return loc;
        }
        ///<summary>
        /// 將字符串形式的IP轉換位long
        ///</summary>
        ///<param name="strIP"></param>
        ///<returns></returns>
        public long IPToLong(string strIP)
        {
            byte[] ip_bytes = new byte[8];
            string[] strArr = strIP.Split(new char[] { '.' });
            for (int i = 0; i < 4; i++)
            {
                ip_bytes[i] = byte.Parse(strArr[3 - i]);
            }
            return BitConverter.ToInt64(ip_bytes, 0);
        }
        ///<summary>
        /// 將索引區字節塊中的起始IP轉換成Long數組
        ///</summary>
        ///<param name="ipBlock"></param>
        long[] BlockToArray(byte[] ipBlock)
        {
            long[] ipArray = new long[ipBlock.Length / 7];
            int ipIndex = 0;
            byte[] temp = new byte[8];
            for (int i = 0; i < ipBlock.Length; i += 7)
            {
                Array.Copy(ipBlock, i, temp, 0, 4);
                ipArray[ipIndex] = BitConverter.ToInt64(temp, 0);
                ipIndex++;
            }
            return ipArray;
        }
        ///<summary>
        /// 從IP數組中搜索指定IP并返回其索引
        ///</summary>
        ///<param name="ipArray">IP數組</param>
        ///<param name="start">指定搜索的起始位置</param>
        ///<param name="end">指定搜索的結束位置</param>
        ///<returns></returns>
        int SearchIP(long[] ipArray, int start, int end)
        {
            int middle = (start + end) / 2;
            if (middle == start)
                return middle;
            else if (ip < ipArray[middle])
                return SearchIP(ipArray, start, middle);
            else
                return SearchIP(ipArray, middle, end);
        }
        ///<summary>
        /// 讀取IP文件中索引區塊
        ///</summary>
        ///<returns></returns>
        byte[] ReadIPBlock()
        {
            long startPosition = ReadLongX(4);
            long endPosition = ReadLongX(4);
            long count = (endPosition - startPosition) / 7 + 1;//總記錄數
            ipFile.Position = startPosition;
            byte[] ipBlock = new byte[count * 7];
            ipFile.Read(ipBlock, 0, ipBlock.Length);
            ipFile.Position = startPosition;
            return ipBlock;
        }
        ///<summary>
        /// 從IP文件中讀取指定字節并轉換位long
        ///</summary>
        ///<param name="bytesCount">需要轉換的字節數,主意不要超過8字節</param>
        ///<returns></returns>
        long ReadLongX(int bytesCount)
        {
            byte[] _bytes = new byte[8];
            ipFile.Read(_bytes, 0, bytesCount);
            return BitConverter.ToInt64(_bytes, 0);
        }
        ///<summary>
        /// 從IP文件中讀取字符串
        ///</summary>
        ///<param name="flag">轉向標志</param>
        ///<returns></returns>
        string ReadString(int flag)
        {
            if (flag == 1 || flag == 2)//轉向標志
                ipFile.Position = ReadLongX(3);
            else
                ipFile.Position -= 1;

            List<byte> list = new List<byte>();
            byte b = (byte)ipFile.ReadByte();
            while (b > 0)
            {
                list.Add(b);
                b = (byte)ipFile.ReadByte();
            }
            return Encoding.Default.GetString(list.ToArray());
        }
    }
}
  • 好的評價 如果您覺得此文章好,就請您
      67%(2)
  • 差的評價 如果您覺得此文章差,就請您
      33%(1)

網絡學院評論評論內容只代表網友觀點,與本站立場無關!

   評論摘要(共 0 條,得分 0 分,平均 0 分) 查看完整評論
皮皮麻将官网下载 北京快3北京福彩网 今晚4场进球彩对阵新浪 (*^▽^*)MG时界门之将军免费下载 彩票平台流水不够提不了现 (★^O^★)MG幸运狮子投注 马报二肖中特 (*^▽^*)MG对决沙龙技巧介绍 (^ω^)MG野性孟加拉虎免费试玩 安徽25选5开奖公告 经典水果老虎机单机版 体彩14场胜负 (★^O^★)MG圣诞大镖客官网 (★^O^★)MG日日进财游戏规则 福建22选5玩法说明书 mg游戏幸运双星技巧 (^ω^)MG花粉之国技巧介绍