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日

相关文章

  • 分享C#操作内存读写方法的主要实现代码

    整体攻略: C#内存操作需要使用System.Runtime.InteropServices命名空间,创建一个Managed代码,来调用Unmanaged C或C++ API,从而实现内存读写。 了解C#的指针类型,使用指针指向内存地址,来进行内存操作。 注意内存读写过程中需要保证线程的安全性,避免数据竞争等问题。 具体实现: 首先需要引入System.Ru…

    C# 2023年6月1日
    00
  • 学习TraceLogging事件,使用ETW记录,并使用WPA捕获和分析跟踪

    优化响应行为的交互 下载WINDOWS评估和部署工具包 (Windows ADK) 保持默认安装 驱动延迟优化的基本步骤包括: 定义方案并添加 TraceLogging 事件。TraceLogging 是用于日志记录事件的系统,无需清单即可解码,TraceLogging基于windows事件跟踪(ETW),并提供检测代码的简化办法。C#可选的有.NET Ev…

    C# 2023年4月27日
    00
  • asp.net(C#)遍历memcached缓存对象

    首先,我们需要了解一下什么是Memcached。Memcached是一种高速缓存系统,它可以将数据存储在内存中,以提高数据访问速度,可用于减轻关系数据库的压力。而ASP.NET(C#)是一种基于Web的开发技术,用于创建动态、数据驱动的网站和Web应用程序。在ASP.NET(C#)应用程序中使用Memcached缓存系统是一个不错的选择,可以提高应用程序的性…

    C# 2023年5月31日
    00
  • 关于Android添加fragment后版本不兼容问题

    当在一个较低的 Android 版本中使用 fragment 时,如果没有处理好版本兼容问题,可能会导致程序崩溃或出现其他不可预知的异常。对于这种问题,我们可以采取以下措施: 1. 使用 support 包 从 Android 3.0 开始,Android 框架引入了 Fragment 和 FragmentManager 等类。然而这些类仅在 Android…

    C# 2023年6月6日
    00
  • C#实现的海盗分金算法实例

    C#实现的海盗分金算法实例,是一种常见的分配问题解决方法,以下是详细的攻略过程: 什么是海盗分金算法? 海盗分金算法,也称为“海盗分赃金问题”,是一种常见的分配问题解决方法。故事背景是这样的:若干个海盗合作得到了一批金子,他们需要分配这批金子。其中,每个海盗都可以提出一个分配方案(包括他自己分到多少金子),其他人可以赞成或反对。如果超过一半的海盗同意,那么分…

    C# 2023年6月7日
    00
  • C++通过Callback向C#传递数据的方法

    使用Callback是一种将C++代码与C#代码连接起来的常用方法。下面是C++通过Callback向C#传递数据的方法的详细攻略。 1.创建一个C#回调方法 首先,需要在C#代码中创建一个接受C++回调的方法。这个方法的参数应该和C++回调方法的参数保持一致,以确保能够正确地接收数据。代码示例如下: public delegate void Callbac…

    C# 2023年6月7日
    00
  • C#控制台基础 list<>初始化的两种方法

    C#中的list是一种通用的、可动态调整的数据结构,通过它可以方便地存储和操作数据。在控制台程序中,初始化list最常见的两种方式是使用构造函数和使用集合初始化器。 使用构造函数初始化list list的构造函数可以接受任何实现IEnumerable接口的对象,它会根据传入的元素类型自动推断出泛型参数类型。下面是使用构造函数初始化list的示例代码: Lis…

    C# 2023年6月1日
    00
  • C#中var关键字用法分析

    C#中var关键字用法分析 在C#中,var关键字可用于声明一个隐式类型的变量,这种类型是在编译器编译时推断出来的。在这篇文章中,我们将详细讲解var关键字的用法,并给出示例说明。 var的用法 1. 声明变量 使用var来声明一个变量时,编译器会自动将该变量的类型推断为其初始化表达式的类型。 var name = "Tom"; var …

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