C# 纯真数据库读取

介绍文章

请参见下面的文章学习如何读取纯真ip数据库的细节

https://www.biaodianfu.com/qqwry-dat.html

代码及使用方法

使用方法

本类可以直接使用

  1. 引入ip数据库解析类
  2. 调用init()函数进行初始化
  3. 使用getIpLctn(string ipStr)函数获取具体的ip地址

效果演示

在这里插入图片描述

具体代码

	/// <summary>
    /// By: YoseZang 2022.09
    /// </summary>
    internal class Program
    {

        static uint frstIdx;
        static uint lstIdx;

        static FileStream fs;
        static BinaryReader br;

        static object lckRd = new object();


        /// <summary>
        /// 首先调用该函数进行初始化
        /// </summary>
        public static void init()
        {
            try
            {
                fs = new FileStream("QQWry.dat", FileMode.Open, FileAccess.Read);
                br = new BinaryReader(fs);
            }
            catch
            {
                fs= null;
                br = null;

                return;
            }

            //获取索引区的位置
            frstIdx = br.ReadUInt32();
            lstIdx = br.ReadUInt32();
        }


        /// <summary>
        /// 检查字符串格式的ip地址是否合法
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        static bool chkIpLgl(string ip)
        {

            Regex rgx = new Regex(@"^(([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$");

            bool rslt;

            rslt = rgx.IsMatch(ip);

            return rslt;
        }

        //获取ip地址的int形式
        static uint getIntIp(string ip)
        {
            string ipHdl = ip.Trim();

            if (chkIpLgl(ip)==false)
            {
                return 0;
            }

            string[] strArr = ip.Split(new string[] { "."}, StringSplitOptions.RemoveEmptyEntries);

            if (strArr.Length<4)
            {
                return 0;
            }

            uint adrs = 0;

            adrs = Convert.ToUInt32(strArr[3]) + Convert.ToUInt32(strArr[2]) * 256 + Convert.ToUInt32(strArr[1]) * 256 * 256 
                + Convert.ToUInt32(strArr[0]) * 256 * 256 * 256;

            return adrs;

        }

        //获取ip地址的字符串形式
        static string getStrIp(uint ip)
        {
            string adrs;

            adrs = "";

            adrs = "." + ip % 256;

            ip = ip / 256;

            adrs = "." + ip % 256+adrs;

            ip = ip / 256;

            adrs = "." + ip % 256 + adrs;

            ip = ip / 256;

            adrs = ip % 256 + adrs;


            return adrs;

        }

        /// <summary>
        /// 获取指定偏移处的uint形式的ip地址
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static uint getIpAtOfst(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            uint ip = br.ReadUInt32();

            return ip;

        }


        /// <summary>
        /// 根据偏移获取指定的位置的3字节文件偏移量数据
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static uint get3BytOfst(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte[] bytArr;
            bytArr = br.ReadBytes(3);

            uint ofst = (uint)bytArr[0] + (uint)bytArr[1] * 256 + (uint)bytArr[2] * 256 * 256;

            return ofst;

        }


        /// <summary>
        /// 根据偏移获取指定的偏移处1字节
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static byte getBytAtPstn(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte byt;
            byt = br.ReadByte();

            return byt;

        }

        /// <summary>
        /// 根据偏移获取指定的偏移处的字符串
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static string getStrAtPstn(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte[] bytArr=new byte[0x500];

            byte byt;

            int sz=0;

            do
            {
                byt = br.ReadByte();

                bytArr[sz] = byt;

                sz++;
            }
            while (byt != 0);

            string str = Encoding.Default.GetString(bytArr,0,sz-1);

            return str;

        }

        /// <summary>
        /// 根据偏移获取指定的偏移处的字符串之后的1字节
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static byte getBytAftStrAtPstn(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte byt;

            do
            {
                byt = br.ReadByte();

            }
            while (byt != 0);

            byt = br.ReadByte();

            //Console.WriteLine("读取的字节是:"+byt );

            return byt;

        }


        /// <summary>
        /// 根据偏移获取指定的偏移处的字符串之后的位置
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static uint getOfstAftStrAtPstn(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte[] bytArr = new byte[0x500];

            byte byt;

            int sz = 0;

            do
            {

                byt = br.ReadByte();

                bytArr[sz] = byt;

                sz++;

            }
            while (byt != 0);

            return (uint)br.BaseStream.Position;

        }

        /// <summary>
        /// 根据偏移获取指定的偏移处的第二个字符串
        /// </summary>
        /// <param name="pstn"></param>
        /// <returns></returns>
        static string getScndStrAtPstn(uint pstn)
        {
            br.BaseStream.Seek(pstn, SeekOrigin.Begin);

            byte[] bytArr = new byte[0x500];

            int sz = 0;

            byte byt;

            do
            {
                byt = br.ReadByte();

            }
            while (byt != 0);

            do
            {

                byt = br.ReadByte();

                bytArr[sz] = byt;

                sz++;

            }
            while (byt != 0);

            string str = Encoding.Default.GetString(bytArr, 0, sz-1);

            return str;

        }


        /// <summary>
        /// 获取ip地址索引的位置
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        static uint getIdxOfst(uint ip)
        {
            uint lPstn = frstIdx;
            uint rPstn = lstIdx;

            uint mPstn, ipMPstn;

            while (lPstn < rPstn)
            {
                
                mPstn = ((rPstn-lPstn)%14==0) ? ( (rPstn - lPstn) / 2 + lPstn) : ((rPstn - lPstn- 7)/2+lPstn);

                ipMPstn = getIpAtOfst(mPstn);

                //Console.WriteLine("mPstn:" + mPstn +" 记录:"+ipMPstn);

                //Thread.Sleep(1000);

                if (ipMPstn > ip)
                {
                    rPstn = mPstn;
                }
                else if (ipMPstn < ip)
                {
                    lPstn = mPstn;


                }
                else if (ipMPstn==ip)
                {
                    lPstn = mPstn;
                    rPstn = mPstn;
                }

                if (rPstn == lPstn + 7)
                {
                    break;
                }

            }

            return lPstn;
        }



        static string getIpDt(uint ofst)
        {

            byte bytSgn;

            bytSgn = getBytAtPstn(ofst + 4);

            string dt, dt2;

            dt = String.Empty;

            dt2 = String.Empty;

            // 模式1 连续存放数据的情况
            if (bytSgn != 0x01 && bytSgn != 0x02)
            {
                //Console.WriteLine("模式1");

                br.BaseStream.Seek(ofst + 4, SeekOrigin.Begin);

                dt = getStrAtPstn(ofst + 4);

                dt2 = getScndStrAtPstn(ofst + 4);

            }



            // 记录模式2 4 5
            if (bytSgn == 0x01)
            {
                //Console.WriteLine("模式245");

                uint dtOfst = get3BytOfst(ofst + 5);

                //Console.WriteLine("字符串之后的数据:" + getBytAftStrAtPstn(dtOfst));

                // 记录模式 2
                if (getBytAtPstn(dtOfst) !=0x01 && getBytAtPstn(dtOfst)!=0x02)
                {
                    //Console.WriteLine("模式2");

                    dt = getStrAtPstn(dtOfst);

                    //Console.WriteLine("记录A:"+dt);

                    if (getBytAftStrAtPstn(dtOfst) != 0x01 && getBytAftStrAtPstn(dtOfst) != 0x02)
                    {
                        dt2 = getScndStrAtPstn(dtOfst);
                    }
                    else
                    {
                        uint dtOfst2 = get3BytOfst( getOfstAftStrAtPstn(dtOfst)+1);

                        dt2 = getStrAtPstn(dtOfst2);

                    }
                    

                    //Console.WriteLine("记录B:" + Encoding.Default.GetBytes(dt2).ToString());

                }
                // 记录模式4 5
                else if (getBytAtPstn(dtOfst)==0x02)
                {
                    //Console.WriteLine("模式45");
                    // 记录模式4
                    if (getBytAtPstn(dtOfst + 4) != 0x01 && getBytAtPstn(dtOfst + 4) != 0x02)
                    {
                        //Console.WriteLine("模式4");
                        uint dtOfst2 = get3BytOfst(dtOfst + 1);

                        dt = getStrAtPstn(dtOfst2);

                        dt2 = getStrAtPstn(dtOfst + 4);
                    }
                    // 记录模式5
                    else
                    {
                        //Console.WriteLine("模式5");
                        uint dtOfst2 = get3BytOfst(dtOfst + 1);

                        dt = getStrAtPstn(dtOfst2);

                        uint dtOfst3 = get3BytOfst(dtOfst + 5);

                        if (dtOfst3 != 0)
                        {
                            dt2 = getStrAtPstn(dtOfst3);
                        }

                        
                    }
                    

                }
            }

            // 记录模式3 记录A被重定向
            if (bytSgn == 0x02)
            {

                //Console.WriteLine("模式3");

                uint dtOfst = get3BytOfst(ofst + 5);

                dt = getStrAtPstn(dtOfst);

                dt2 = getStrAtPstn(ofst + 8);

            }

            if (dt.Contains("CZ88.NET"))
            {
                dt = String.Empty;
            }

            if (dt2.Contains("CZ88.NET"))
            {
                dt2 = String.Empty;
            }

            return dt + " " + dt2;

        }

        public static string getIpLctn(string ipStr)
        {
            uint ip, idxOfst, dtOfst;

            string str;

            lock (lckRd)
            {
                if (chkIpLgl(ipStr) == false)
                {
                    return String.Empty;
                }

                ip = getIntIp(ipStr);
                idxOfst = getIdxOfst(ip);
                dtOfst = get3BytOfst(idxOfst + 4);

                str = string.Empty;

                str = getIpDt(dtOfst);

                Console.WriteLine("位置信息:"+str);
                //MessageBox.Show(str);
            }

            return str;

        }
		
		/// <summary>
        /// 测试函数
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            init();

            string ipStr;


            while (true)
            {
                Console.Write("请输入Ip地址:");
                ipStr = Console.ReadLine();
                Console.WriteLine("匹配ip地址规则:" + chkIpLgl(ipStr));
                Console.WriteLine(getIpLctn(ipStr));
            }
           
            Console.ReadLine();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoseZang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值