Пример #1
0
        /// <summary>
        /// Gets country code from an IPv4 address.
        /// </summary>
        private string getCountryCodeIPv4(IPAddress addr)
        {
            // Get IP address as unsigned 32-bit
            byte[] bytes = addr.GetAddressBytes();
            UInt32 val   = 0;

            for (int i = 0; i != bytes.Length; ++i)
            {
                val <<= 8;
                val  += bytes[i];
            }
            // Find largest RangeFirst that's not greater than value
            // Binary search on ranges sorted by their first values
            int bottom = 0;
            int top    = ip4Ranges.Length - 1;
            int middle = top >> 1;

            while (top >= bottom)
            {
                if (ip4Ranges[middle].RangeFirst == val)
                {
                    break;
                }
                if (ip4Ranges[middle].RangeFirst > val)
                {
                    top = middle - 1;
                }
                else
                {
                    bottom = middle + 1;
                }
                middle = (bottom + top) >> 1;
            }
            // We're looking for equal or nearest smaller
            while (middle > 0 && ip4Ranges[middle].RangeFirst > val)
            {
                --middle;
            }
            IPv4Range range = ip4Ranges[middle];

            // We just have a larger one: no country
            if (range.RangeFirst > val)
            {
                return(GetNoCountry());
            }
            // We're actually within range: return that country
            if (range.RangeFirst <= val && range.RangeLast >= val)
            {
                return(countries[range.CountryId]);
            }
            // No country
            return(GetNoCountry());
        }
Пример #2
0
        /// <summary>
        /// Serializes IP range data in binary form.
        /// </summary>
        public void WriteBin(BinaryWriter bw)
        {
            // Number of ranges
            UInt32 count = (UInt32)ip4Ranges.Length;

            bw.Write(count);
            // Write each range
            for (UInt32 i = 0; i != count; ++i)
            {
                IPv4Range range = ip4Ranges[i];
                bw.Write(range.RangeFirst);
                bw.Write(range.RangeLast);
                bw.Write(range.CountryId);
            }
        }
Пример #3
0
        /// <summary>
        /// Reads IPv4 range file; returns sorted array, with contiguous same-country ranges merged.
        /// </summary>
        private IPv4Range[] loadIp4(StreamReader sr)
        {
            // Reserve
            List <IPv4Range> res = new List <IPv4Range>(180000);
            // Parse file
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                if (line == string.Empty || line.StartsWith("#"))
                {
                    continue;
                }
                string[] parts     = getParts(line);
                UInt32   first     = UInt32.Parse(parts[0]);
                UInt32   last      = UInt32.Parse(parts[1]);
                string   country   = parts[5];
                byte     countryId = getCountryId(country);
                res.Add(new IPv4Range {
                    RangeFirst = first, RangeLast = last, CountryId = countryId
                });
            }
            // Sort by range starts
            res.Sort((a, b) => a.RangeFirst.CompareTo(b.RangeFirst));
            // Eliminate duplicates
            List <IPv4Range> cpy = new List <IPv4Range>(res.Count);

            cpy.Add(res[0]);
            for (int i = 1; i < res.Count; ++i)
            {
                IPv4Range curr = res[i];
                IPv4Range prev = cpy[cpy.Count - 1];
                // Current range is contiguous to previous one; same country too
                if (curr.CountryId == prev.CountryId && curr.RangeFirst == prev.RangeLast + 1)
                {
                    prev.RangeLast     = curr.RangeLast;
                    cpy[cpy.Count - 1] = prev;
                }
                // Nop, add new item
                else
                {
                    cpy.Add(curr);
                }
            }
            // Return redcued array (with contiguous country ranges merged)
            return(cpy.ToArray());
        }