C#读取QQ纯真IP数据库QQWry.Dat的代码

下面是详细的攻略。

1. 下载QQ纯真IP数据库QQWry.Dat

首先,我们需要先下载QQ纯真IP数据库QQWry.Dat,可以从官网下载(http://www.cz88.net/),也可以搜索下载链接。

2. 使用C#读取QQ纯真IP数据库

读取QQ纯真IP数据库QQWry.Dat,我们需要用到二进制读取和文件指针的知识。以下是读取QQWry.Dat的代码示例:

示例1

using System;
using System.IO;
using System.Text;

public class IPHelper
{
    private static FileStream fs;
    private static BinaryReader br;

    private static long left;
    private static long right;
    private static long middle;

    private static uint countryOffset;
    private static uint recordOffset;

    private static byte[] buffer = new byte[8];
    private static byte[] recordBuffer = new byte[40];

    public static void Init(string fileName)
    {
        if (File.Exists(fileName))
        {
            fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
            br = new BinaryReader(fs);

            left = br.ReadInt32();
            right = br.ReadInt32();

            countryOffset = br.ReadUInt32();
            recordOffset = ReadUInt32();
        }
        else
        {
            throw new Exception(string.Format("文件 {0} 不存在。", fileName));
        }
    }

    public static void Query(string ip)
    {
        uint ipValue = IP2Long(ip);

        while (left <= right)
        {
            middle = (left + right) / 2;
            long offset = countryOffset + middle * 7;
            fs.Seek(offset, SeekOrigin.Begin);
            br.Read(buffer, 0, 4);
            uint startIP = GetUInt32(buffer, 0);

            if (ipValue < startIP)
            {
                right = middle - 1;
            }
            else
            {
                offset += 4;
                fs.Seek(offset, SeekOrigin.Begin);
                br.Read(buffer, 0, 3);
                uint endIP = GetUInt32(buffer, 0);

                if (ipValue > endIP)
                {
                    left = middle + 1;
                }
                else
                {
                    offset += 1;
                    fs.Seek(offset, SeekOrigin.Begin);
                    recordOffset = ReadUInt32();
                    fs.Seek(recordOffset, SeekOrigin.Begin);
                    br.Read(recordBuffer, 0, 40);
                    string country = GetLocation(recordBuffer);
                    country = Encoding.Default.GetString(Encoding.Default.GetBytes(country));
                    string[] locationArray = country.Split('\t');
                }
            }
        }
    }

    private static uint ReadUInt32()
    {
        br.Read(buffer, 0, 4);
        return GetUInt32(buffer, 0);
    }

    private static uint GetUInt32(byte[] value, int startIndex)
    {
        uint result = (uint)value[startIndex];
        result |= (uint)value[startIndex + 1] << 8;
        result |= (uint)value[startIndex + 2] << 16;
        result |= (uint)value[startIndex + 3] << 24;

        return result;
    }

    private static uint IP2Long(string ip)
    {
        string[] ips = ip.Split('.');
        uint ipValue = 0;
        if (ips.Length == 4)
        {
            try
            {
                ipValue = (uint.Parse(ips[0]) << 24) |
                          (uint.Parse(ips[1]) << 16) |
                          (uint.Parse(ips[2]) << 8) |
                          (uint.Parse(ips[3]));
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Wrong IP format : {0}", ex.Message));
            }
        }
        else
        {
            throw new Exception(string.Format("Wrong IP format : {0}", ip));
        }

        return ipValue;
    }

    private static string GetLocation(byte[] recordBuffer)
    {
        uint countryOffset = GetUInt32(recordBuffer, 0);

        if (countryOffset == 0x01)
        {
            countryOffset = GetUInt32(recordBuffer, 4);
        }

        int length = (int)countryOffset - 0x01;
        byte[] location = new byte[length];

        Array.Copy(recordBuffer, 8, location, 0, length);

        return Encoding.Default.GetString(location);
    }
}

示例2

public class IPInfo
{
    public string Country { get; set; }
    public string Area { get; set; }
}

public class IPHelper2
{
    private static uint startPos = 0;
    private static FileStream fs = null;
    private static byte[] buf = null;
    private static byte[] IPHeadArr = null; //数据头
    private static uint EndPos = 0;  //最后的位置

    public static void Init(string IpFilePath)
    {
        buf = new byte[4];
        IPHeadArr = new byte[256];
        fs = new FileStream(IpFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        EndPos = ReadUInt32(0);
        fs.Seek(0x100, SeekOrigin.Begin);
        fs.Read(IPHeadArr, 0, 256);
    }

    //返回的IPInfo
    public static IPInfo ReadIP(string ip)
    {
        uint ipNum = IP2UInt(ip);
        uint pointVal = SearchIPData(ipNum);
        if (pointVal == 0)
            return null;
        else
        {
            int offset = 0;
            if (ReadUInt8(pointVal + 4) == 0x02)
            {
                offset = ReadToUInt24(pointVal + 5);
                pointVal = SearchIPData(ReadUInt32(pointVal + 8));
            }
            else
            {
                offset = 4;
            }
            string country = ReadString(offset + pointVal);
            if (country[country.Length - 1] == '\0')
                country = country.Substring(0, country.Length - 1);
            if (ReadUInt8(pointVal + offset + 1) == 0x02)
            {
                offset = ReadToUInt24(pointVal + offset + 2);
                pointVal = ReadUInt32(pointVal + offset + 4);
            }
            else
            {
                pointVal += ReadUInt8(pointVal + offset + 1) + 1;
            }
            string province = ReadString(offset + pointVal);
            if (province[province.Length - 1] == '\0')
                province = province.Substring(0, province.Length - 1);

            var ipinfo = new IPInfo() { Country = country, Area = province };

            return ipinfo;
        }
    }

    //找到数据
    private static uint SearchIPData(uint ipNum)
    {
        uint part1 = (ipNum & 0xFF000000) >> 24;
        if (IPHeadArr[part1] == 0) return 0;
        if (IPHeadArr[part1] == 1)
        {
            return ReadUInt32((part1 << 8) + 0x100);
        }
        uint part2 = (ipNum & 0x00FF0000) >> 16;
        uint pointVal = ReadUInt32(((uint)(IPHeadArr[part1]) << 8) + part2);
        if (pointVal == 0) return 0;
        if (ReadUInt8(pointVal + 4) == 0x01)
            return pointVal;
        if (ReadUInt8(pointVal + 4) == 0x02)
            return ReadUInt32(pointVal + 8) ;
        return 0;
    }

    //将192.168.15.12形式的IP转换成UInt32
    private static uint IP2UInt(string ip)
    {
        string[] nums = ip.Split('.');
        uint ip0 = uint.Parse(nums[0]);
        uint ip1 = uint.Parse(nums[1]);
        uint ip2 = uint.Parse(nums[2]);
        uint ip3 = uint.Parse(nums[3]);
        return (ip0 << 24) | (ip1 << 16) | (ip2 << 8) | ip3;
    }

    //读取记录区中的标志字段
    private static uint ReadFlag(uint offset)
    {
        fs.Position = offset;
        fs.Read(buf, 0, 4);
        return BitConverter.ToUInt32(buf, 0);
    }

    //读取记录区中的三个字节
    private static int ReadToUInt24(uint offset)
    {
        byte[] b3 = new byte[4];
        b3[0] = 0;
        fs.Position = offset;
        fs.Read(b3, 1, 3);
        return BitConverter.ToInt32(b3, 0);
    }

    //读取记录区字符串
    private static string ReadString(uint offset)
    {
        fs.Position = offset;
        int len = 0;
        while (fs.ReadByte() != 0) len++;
        fs.Position = offset;
        byte[] bytes = new byte[len];
        fs.Read(bytes, 0, len);

        return Encoding.GetEncoding("GB2312").GetString(bytes);
    }

    //读取指定偏移处的UInt32值
    private static uint ReadUInt32(uint offset)
    {
        fs.Position = offset;
        fs.Read(buf, 0, 4);
        return BitConverter.ToUInt32(buf, 0);
    }

    //读取指定偏移处的Byte值
    private static byte ReadUInt8(uint offset)
    {
        fs.Position = offset;
        return (byte)fs.ReadByte();
    }
}

3. 总结

以上是使用C#读取QQ纯真IP数据库QQWry.Dat的两个代码示例。虽然两个示例的实现方式不同,但实现的功能是一致的。我们还可以根据自己的需求进行相应的调整。

阅读剩余 84%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#读取QQ纯真IP数据库QQWry.Dat的代码 - Python技术站

(0)
上一篇 2023年6月2日
下一篇 2023年6月2日

相关文章

  • C#编写游戏客户端的实现代码

    C#编写游戏客户端的实现代码攻略 前言 C#是一种现代化的高级编程语言,它具有简洁的语法、面向对象的特性和丰富的类库,适用于各种不同类型的游戏开发。本攻略介绍了如何使用C#编写游戏客户端的实现代码,包含了从连接服务器到收发数据的完整过程。 步骤 1. 连接服务器 使用C#编写游戏客户端的第一步是连接到游戏服务器。可以使用System.Net.Sockets命…

    C# 2023年5月15日
    00
  • C#强制转换和尝试转换的方法

    C#中的类型转换分为强制转换和尝试转换两种方法。 强制转换 强制转换是将一种数据类型转换为另一种数据类型,如果无法转换则会在运行时产生异常。在C#中,强制转换使用一对小括号来实现,括号中放置需要被转换的数据类型。例如: int i = 10; double d = (double)i; 在这个例子中,将一个整型变量i强制转换为double类型,结果存储在另一…

    C# 2023年5月15日
    00
  • 用powershell开发跨平台动态网页

    powershell 动态 网页 跨平台 asp.net dynamic cross platform powershell 传教士 原创文章。始于 2023-04-03 允许转载,但必须保留名字和出处 —【前言】— 以【vbs,和微软jsript】为核心的asp已经淘汰了。ie11后来都不支持网页内嵌vbs了。asp前后端不分离,jscript非正…

    C# 2023年4月18日
    00
  • mvc C# JavaScript LigerUI oracle实现用户的注册、登陆验证、登陆

    实现用户的注册、登陆验证和登陆的过程中,我们可以使用以下技术: MVC框架:它可以帮助我们轻松地管理代码和文件,并且可以轻松地将应用程序升级到不同的版本。 C#语言:它是一种强类型的语言,广泛用于.NET平台上的应用程序开发。 JavaScript:它是一种客户端编程语言,广泛用于Web开发。 LigerUI:它是一个开源的跨平台Web前端UI框架,受到了广…

    C# 2023年5月15日
    00
  • C#处理MySql多个返回集的方法

    下面是关于“C#处理MySql多个返回集的方法”的完整攻略: 目录 什么是多个返回集 处理多个返回集的方法 示例介绍 示例1:使用MySqlDataReader.NextResult方法读取多个返回集 示例2:使用DataSet类读取多个返回集 总结 什么是多个返回集 在使用MySql数据库时,有时一个存储过程或者一个查询语句可能会返回多个数据集,这就是多个…

    C# 2023年5月31日
    00
  • 在C#使用字典存储事件示例及实现自定义事件访问器

    在C#中,我们可以使用字典作为存储事件的数据结构来方便地处理事件的订阅和触发。以下是一些实现自定义事件访问器的步骤: 1. 声明事件 首先,我们需要声明事件。事件是一种操作,它在特定条件下会被触发。在C#中,事件可以理解为委托的实例化。下面是一个声明事件的示例: public event Action<string> MyEvent; 这里声明了…

    C# 2023年5月31日
    00
  • ASP.NET Core 依赖注入框架的使用

    在 ASP.NET Core 中,依赖注入(Dependency Injection,DI)是一种设计模式,它可以帮助我们管理应用程序中的对象和服务。ASP.NET Core 内置了一个依赖注入框架,可以帮助我们轻松地实现依赖注入。以下是 ASP.NET Core 依赖注入框架的完整攻略: 步骤一:注册服务 在 ASP.NET Core 中,可以使用 Con…

    C# 2023年5月17日
    00
  • C#快速实现IList非泛型类接口的自定义类作为数据源

    要快速实现IList非泛型类接口的自定义类作为数据源,可以按照以下步骤进行: 在自定义类中添加IList接口实现 public class MyList : IList { // 实现IList接口需要的属性和方法 // … } 实现IList接口需要的属性和方法 IList接口需要实现的属性和方法比较多,包括索引器、Add、Clear、Contains…

    C# 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部