Exemple #1
0
        /// <summary>
        ///  从IP文件中读取指定字节并转换位long
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="bytesCount">需要转换的字节数,主意不要超过8字节</param>
        /// <returns></returns>
        private long ReadLongX(IpDbAccessor stream, int bytesCount)
        {
            var bytes = new byte[8];

            stream.Read(bytes, 0, bytesCount);
            return(BitConverter.ToInt64(bytes, 0));
        }
Exemple #2
0
        ///<summary>
        ///查找IP地址所在的绝对偏移量
        ///</summary>
        ///<param name="ip"></param>
        ///<returns></returns>
        private long locateIP(IpDbAccessor ipFile, byte[] ip)
        {
            long m = 0;
            int  r;
            var  b4 = new byte[4];

            //比较第一个IP项
            readIP(ipFile, _startPosition, b4);
            r = compareIP(ip, b4);
            if (r == 0)
            {
                return(_startPosition);
            }
            else if (r < 0)
            {
                return(-1);
            }
            //开始二分搜索
            for (long i = _startPosition, j = _endPosition; i < j;)
            {
                m = this.getMiddleOffset(i, j);
                readIP(ipFile, m, b4);
                r = compareIP(ip, b4);
                if (r > 0)
                {
                    i = m;
                }
                else if (r < 0)
                {
                    if (m == j)
                    {
                        j -= IP_RECORD_LENGTH;
                        m  = j;
                    }
                    else
                    {
                        j = m;
                    }
                }
                else
                {
                    ipFile.Position = m + 4;
                    return(ReadLongX(ipFile, 3));//readLong3(m + 4);
                }
            }
            ipFile.Position = m + 4;
            m = ReadLongX(ipFile, 3);//readLong3(m + 4);
            readIP(ipFile, m, b4);
            r = compareIP(ip, b4);
            if (r <= 0)
            {
                return(m);
            }
            else
            {
                return(-1);
            }
        }
Exemple #3
0
        ///<summary>
        ///从当前位置读取3字节
        ///</summary>
        ///<returns></returns>
        private long readLong3(IpDbAccessor ipFile)
        {
            long ret = 0;

            ret |= Convert.ToInt64(ipFile.ReadByte() & 0xFF);
            ret |= Convert.ToInt64((ipFile.ReadByte() << 8) & 0xFF00);
            ret |= Convert.ToInt64((ipFile.ReadByte() << 16) & 0xFF0000);
            return(ret);
        }
Exemple #4
0
        ///<summary>
        ///根据当前位置,读取3字节
        ///</summary>
        ///<param name="offset"></param>
        ///<returns></returns>
        private long readLong3(IpDbAccessor ipFile, long offset)
        {
            long ret = 0;

            ipFile.Position = offset;
            ret            |= Convert.ToInt64(ipFile.ReadByte() & 0xFF);
            ret            |= Convert.ToInt64((ipFile.ReadByte() << 8) & 0xFF00);
            ret            |= Convert.ToInt64((ipFile.ReadByte() << 16) & 0xFF0000);
            return(ret);
        }
Exemple #5
0
        ///<summary>
        ///从当前位置读取四字节,此四字节是IP地址
        ///</summary>
        ///<param name="offset"></param>
        ///<param name="ip"></param>
        private void readIP(IpDbAccessor ipFile, long offset, byte[] ip)
        {
            ipFile.Position = offset;
            ipFile.Read(ip, 0, ip.Length);
            byte tmp = ip[0];

            ip[0] = ip[3];
            ip[3] = tmp;
            tmp   = ip[1];
            ip[1] = ip[2];
            ip[2] = tmp;
        }
Exemple #6
0
        /// <inheritdoc />
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public virtual async Task <bool> InitAsync(bool getNewDb = false, CancellationToken token = default(CancellationToken))
        {
            if (_init != null && !getNewDb)
            {
                return(_init.Value);
            }

            await _initLock.WaitAsync(token);

            try
            {
                if (_init != null && !getNewDb)
                {
                    return(_init.Value);
                }


                var isExist = DbFileExist(_qqwryOptions.DbPath);
                if (!isExist || getNewDb)
                {
                    await UpdateDbAsync();
                }

#if DEBUG
                System.Diagnostics.Debug.WriteLine("使用IP数据库{0}", _qqwryOptions.DbPath);
#endif
                _qqwryDbBytes = FileToBytes(_qqwryOptions.DbPath);

                var ipFile = new IpDbAccessor(_qqwryDbBytes);
                _startPosition = ReadLongX(ipFile, 4);
                _endPosition   = ReadLongX(ipFile, 4);

                //总记录数
                _ipCount = Convert.ToInt32((_endPosition - _startPosition) / IP_RECORD_LENGTH + 1);

                _version = null;
                _init    = true;
            }
            finally
            {
                _initLock.Release();
            }

            if (_qqwryDbBytes == null)
            {
                throw new InvalidOperationException("无法打开IP数据库" + _qqwryOptions.DbPath + "!");
            }

            return(true);
        }
Exemple #7
0
        /// <inheritdoc />
        /// <summary>
        /// 初始化
        /// </summary>
        /// <returns></returns>
        public virtual bool Init(bool getNewDb = false)
        {
            if (_init != null && !getNewDb)
            {
                return(_init.Value);
            }
            _initLock.Wait();
            try
            {
                if (_init != null && !getNewDb)
                {
                    return(_init.Value);
                }

                var isExist = DbFileExist(_qqwryOptions.DbPath);
                if (!isExist || getNewDb)
                {
                    UpdateDb();
                }

#if DEBUG
                System.Diagnostics.Debug.WriteLine(format: $"使用IP数据库{_qqwryOptions.DbPath}");
#endif

                _qqwryDbBytes = FileToBytes(_qqwryOptions.DbPath);

                var ipFile = new IpDbAccessor(_qqwryDbBytes);
                _startPosition = ReadLongX(ipFile, 4);
                _endPosition   = ReadLongX(ipFile, 4);

                //总记录数
                _ipCount = Convert.ToInt32((_endPosition - _startPosition) / IP_RECORD_LENGTH + 1);

                _version = null;
                _init    = true;
            }
            finally
            {
                _initLock.Release();
            }

            if (_qqwryDbBytes == null)
            {
                throw new InvalidOperationException("无法打开IP数据库" + _qqwryOptions.DbPath + "!");
            }

            return(true);
        }
Exemple #8
0
        ///<summary>
        ///取得具体信息
        ///</summary>
        ///<param name="offset"></param>
        ///<returns></returns>
        private IpLocation getIPLocation(IpLocation loc, IpDbAccessor ipFile, long offset)
        {
            ipFile.Position = offset + 4;
            //读取第一个字节判断是否是标志字节
            byte one = (byte)ipFile.ReadByte();

            if (one == REDIRECT_MODE_1)
            {
                //第一种模式
                //读取国家偏移
                long countryOffset = ReadLongX(ipFile, 3);//readLong3();
                //转至偏移处
                ipFile.Position = countryOffset;
                //再次检查标志字节
                byte b = (byte)ipFile.ReadByte();
                if (b == REDIRECT_MODE_2)
                {
                    loc.Country     = readString(ipFile, ReadLongX(ipFile, 3));//readString(readLong3());
                    ipFile.Position = countryOffset + 4;
                }
                else
                {
                    loc.Country = readString(ipFile, countryOffset);
                }
                //读取地区标志
                loc.Area = readArea(ipFile, ipFile.Position);
            }
            else if (one == REDIRECT_MODE_2)
            {
                //第二种模式
                loc.Country = readString(ipFile, ReadLongX(ipFile, 3));//readString(readLong3());
                loc.Area    = readArea(ipFile, offset + 8);
            }
            else
            {
                //普通模式
                loc.Country = readString(ipFile, --ipFile.Position);
                loc.Area    = readString(ipFile, ipFile.Position);
            }
            return(loc);
        }
Exemple #9
0
        ///<summary>
        ///读取字符串
        ///</summary>
        ///<param name="offset"></param>
        ///<returns></returns>
        private string readString(IpDbAccessor ipFile, long offset)
        {
            var buf = new byte[100];

            ipFile.Position = offset;
            int i = 0;

            for (i = 0, buf[i] = (byte)ipFile.ReadByte();
                 buf[i] != (byte)(0); buf[++i] = (byte)ipFile.ReadByte())
            {
                ;
            }
            if (i > 0)
            {
                return(_encodingGb2312.GetString(buf, 0, i));
            }
            else
            {
                return("");
            }
        }
Exemple #10
0
        ///<summary>
        ///搜索IP地址搜索
        ///</summary>
        ///<param name="ip"></param>
        ///<returns></returns>
        public IpLocation ReadLocation(IpLocation loc, string ip)
        {
            //将字符IP转换为字节
            string[] ipSp = ip.Split('.');
            if (ipSp.Length != 4)
            {
                throw new ArgumentOutOfRangeException("不是合法的IP地址!");
            }
            byte[] IP = new byte[4];
            for (int i = 0; i < IP.Length; i++)
            {
                IP[i] = (byte)(int.Parse(ipSp[i]) & 0xFF);
            }
            var  ipFile = new IpDbAccessor(_qqwryDbBytes);
            long offset = locateIP(ipFile, IP);

            if (offset != -1)
            {
                loc = getIPLocation(loc, ipFile, offset);
            }
            return(loc);
        }
Exemple #11
0
        ///<summary>
        ///读取地区名称
        ///</summary>
        ///<param name="offset"></param>
        ///<returns></returns>
        private string readArea(IpDbAccessor ipFile, long offset)
        {
            ipFile.Position = offset;
            byte one = (byte)ipFile.ReadByte();

            if (one == REDIRECT_MODE_1 || one == REDIRECT_MODE_2)
            {
                ipFile.Position = offset + 1;
                long areaOffset = ReadLongX(ipFile, 3);//readLong3(offset + 1);
                if (areaOffset == 0)
                {
                    return(unArea);
                }
                else
                {
                    return(readString(ipFile, areaOffset).Replace(" CZ88.NET", ""));
                }
            }
            else
            {
                return(readString(ipFile, offset).Replace(" CZ88.NET", ""));
            }
        }