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的两个代码示例。虽然两个示例的实现方式不同,但实现的功能是一致的。我们还可以根据自己的需求进行相应的调整。

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

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

相关文章

  • ASP.Net Core基于ABP架构配置To Json序列化

    ASP.Net Core是一个非常流行的Web开发框架,而ABP则为开发者提供了很多基础框架和模块来简化开发流程,因此很多开发者选择使用ABP来开发自己的ASP.Net Core应用程序。在使用ABP中,有时候需要将对象转换成JSON字符串,这时可以使用To Json序列化,下面介绍ASP.Net Core基于ABP架构配置To Json序列化的详细攻略。 …

    C# 2023年5月31日
    00
  • .net中as和is之间的区别分析

    我来为你详细讲解一下“.net中as和is之间的区别分析”。 1. as和is的基本使用 在.NET中,as和is都是类型操作符,用于类型转换或类型检查。 1.1 as操作符 as操作符用于将一个引用类型转换为另外一个引用类型,或将一个类类型转换为其派生类型。如果转换失败,则as返回null,而不是抛出异常。例子如下: object obj = "…

    C# 2023年5月31日
    00
  • C#类的创建与初始化实例解析

    C# 是一种面向对象的编程语言,它的类是其最重要的组成单元。在 C# 中,类可以被定义为模板或蓝图,用来描述一个对象需要包含哪些属性和行为。本文将介绍如何创建和初始化 C# 类的实例,以及解析这些实例的一些常见方法。 创建 C# 类 要创建一个 C# 类,需要遵循以下步骤: 使用 class 关键字定义类的名称,如: public class MyClass…

    C# 2023年5月31日
    00
  • C#连接蓝牙设备的实现示例

    下面是详细的“C#连接蓝牙设备的实现示例”的攻略,包含两条示例: 一、连接蓝牙设备的前置知识 连接蓝牙设备需要以下前置知识: 确定蓝牙设备的名称或 MAC 地址。 确认蓝牙设备支持的服务及特征值。这些信息通常可以找到蓝牙设备的对应文档中或通过蓝牙调试工具获得。 确保本机已经安装了支持蓝牙通信的驱动程序和 .NET Framework 版本 >= 3.5…

    C# 2023年5月15日
    00
  • ASP.NET Core自定义中间件的方式详解

    ASP.NET Core自定义中间件的方式详解 在ASP.NET Core中,中间件是一种非常强大的机制,可以在请求管道中执行自定义逻辑。本攻略将提供一些示例,演示如何在ASP.NET Core中创建自定义中间件。 步骤 步骤1:创建.NET Core Web API项目 首先,需要创建一个.NET Core Web API项目。可以使用以下命令在命令行中创…

    C# 2023年5月17日
    00
  • C# 使用modbus 读取PLC 寄存器地址的方法

    C#是一种强类型编程语言,用于开发.NET框架下的应用程序。 Modbus是一种在工业自动化领域广泛使用的通讯协议,用于在PLC和其他设备之间进行通信。在本篇文章中,我们将详细讲解C#使用Modbus读取PLC寄存器地址的方法。 准备工作 在开始之前,必须做以下准备工作: 安装.Net框架; 准备好一个Modbus通讯的PLC设备; 下载和安装一个支持Mod…

    C# 2023年5月15日
    00
  • C#使用oledb读取excel表格内容到datatable的方法

    关于“C#使用oledb读取Excel表格内容到DataTable的方法”的攻略,我可以这样来进行详细讲解。 1. 需求 我们的需求是读取Excel表格的内容,并将其存储到DataTable中,以便于进行后续的操作和处理。 2. 准备工作 需要安装Microsoft ACE OLEDB运行库才能正常使用,还需要添加System.Data命名空间。 3. 读取…

    C# 2023年5月15日
    00
  • C#反射机制介绍

    C#反射机制介绍 C#中的反射机制是一种强大的工具,可以在程序运行时动态地获取类型信息、创建对象以及调用对象的方法和属性等操作,这使得我们可以编写更加灵活、可扩展的程序。 获取类型信息 在C#中,使用Type类来获取类型信息。通常可以使用typeof运算符获取类型的信息,例如: Type t = typeof(string); 也可以使用对象的GetType…

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