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# Stream.Write – 向流中写入数据

    C#的Stream.Write方法是用于向流中写入数据的方法,其作用是将字节数组中的内容写入到流中。该方法可以用于写入任何类型的数据,包括文本、图像、声音等。 以下是该方法的使用方法的完整攻略: 打开流对象:在使用该方法之前,需要打开流对象。打开流对象可以使用FileStream类、MemoryStream类、NetworkStream类等。根据需要选择相应…

    C# 2023年4月19日
    00
  • ASP.NET中常用的三十三种代码第6/7页

    ASP.NET中常用的三十三种代码是一份非常实用的代码攻略,里面详细介绍了 ASP.NET 中常用的三十三种代码技巧及其应用场景。 下面我将结合具体的示例来详细讲解攻略的一些关键知识点。 Chapter 6:多语言和本地化 在多语言和本地化方面,攻略中提供了许多有用的代码技巧,可以帮助我们在国际化的环境中更加方便地开发应用。下面介绍两个示例: 示例1:在页面…

    C# 2023年5月31日
    00
  • c# 获取CookieContainer的所有cookies函数代码

    下面我就为您详细讲解“c# 获取CookieContainer的所有cookies函数代码”的完整攻略。 1. 什么是CookieContainer? CookieContainer类是System.Net命名空间下的一个类,用于管理网站的Cookie信息,其中包含了多个Cookie对象。在C#编程中,我们可以通过对CookieContainer类的操作实现…

    C# 2023年5月31日
    00
  • C#基于百度AI实现机器翻译功能

    下面是“C#基于百度AI实现机器翻译功能”完整攻略的详细讲解。 1. 准备工作 在开始实现机器翻译功能之前,我们需要先准备好所需要的资源和工具: 1.1 安装百度AI SDK 访问百度AI开放平台并注册账号,然后可以在控制台获取到 api_key 和 secret_key。 百度AI SDK提供了各种AI相关的服务,我们需要安装其中的机器翻译SDK,可以通过…

    C# 2023年5月31日
    00
  • C#实现在窗体上的统计图效果

    首先,在窗体上实现统计图效果的方式有很多种,以下是其中一种具体的实现方法,具体攻略如下: 1. 准备工作 在使用C#实现窗体上统计图效果之前,我们需要确保以下几点: 确保在Visual Studio中安装了Windows Forms应用程序工具包 确保在Windows Form中添加了一个Chart控件 2. 设定数据源 在Chart控件中使用数据源,可以是…

    C# 2023年6月6日
    00
  • C#多线程之Semaphore用法详解

    C#多线程之Semaphore用法详解 概述 Semaphore 用来控制同时访问特定资源的线程数量,可以用来实现线程的同步和互斥。Semaphore 维护了一个计数器,表示可用的资源数量。每个线程在访问资源之前都需要对 Semaphore 进行等待,如果 Semaphore 的计数器大于 0,则线程可以继续执行,同时 Semaphore 的计数器会减 1,…

    C# 2023年5月15日
    00
  • 如何使用C#操作幻灯片

    如何使用C#操作幻灯片 操作幻灯片涉及到的主要对象有幻灯片(Presentation)、幻灯片文档(Slide)和幻灯片放映(PresentationSlideShow)。在C#中,可以通过Microsoft.Office.Interop.PowerPoint命名空间下的对象来对幻灯片进行操作。 以下是使用C#操作幻灯片的详细攻略: 步骤1:启用Office…

    C# 2023年6月6日
    00
  • C#中的值传递和引用传递详细解析

    C#中的值传递和引用传递详细解析 在C#语言中,函数参数传递过程中存在值传递和引用传递两种方式。它们的区别在于传递的方式不同,对于函数中的操作也会造成不同的影响。 值传递(Value Types) 值传递是指将参数值的副本传入函数内部。在函数中对参数值的任何改变都只会影响到该参数的副本,不会影响到原始值。 示例一: public static void Ma…

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