class CountryLookup::Lookup
Public Class Methods
new()
click to toggle source
# File lib/country_lookup.rb, line 4 def initialize initialize_from_file end
Public Instance Methods
lookup_ip_number(ip_number)
click to toggle source
# File lib/country_lookup.rb, line 25 def lookup_ip_number(ip_number) index = self.binary_search(ip_number) cc = @country_codes[index] if cc == '--' return nil end cc end
lookup_ip_string(ip_string)
click to toggle source
# File lib/country_lookup.rb, line 8 def lookup_ip_string(ip_string) if ip_string.nil? || ip_string.empty? return nil end components = ip_string.split('.') if components.length < 4 return nil end ip_number = components[0].to_i * 16777216 + components[1].to_i * 65536 + components[2].to_i * 256 + components[3].to_i self.lookup_ip_number(ip_number) end
Private Instance Methods
binary_search(value)
click to toggle source
# File lib/country_lookup.rb, line 36 def binary_search(value) min = 0 max = @ip_ranges.length - 1 while min < max do mid = (min + max) >> 1 if @ip_ranges[mid] <= value min = mid + 1 else max = mid end end min end
initialize_from_file()
click to toggle source
The binary is packed as follows: c1.c2.c3.….**: Country code look up table, terminated by **
n1.c: if n is < 240, c is country code index 242.n2.n3.c: if n >= 240 but < 65536. n2 being lower order byte 243.n2.n3.n4.c: if n >= 65536. n2 being lower order byte
# File lib/country_lookup.rb, line 57 def initialize_from_file unless @country_codes.nil? || @country_codes.length == 0 return end @country_codes = Array.new @ip_ranges = Array.new @country_table = Array.new File.open(File.dirname(__FILE__) + '/ip_supalite.table') do |file| until file.eof? c1 = file.read(1) c2 = file.read(1) @country_table.push(c1 + c2) if (c1 == '*') break end end last_end_range = 0 until file.eof? count = 0 n1 = file.read(1).ord if n1 < 240 count = n1 elsif n1 == 242 n2 = file.read(1).ord n3 = file.read(1).ord count = n2 | (n3 << 8) elsif n1 == 243 n2 = file.read(1).ord n3 = file.read(1).ord n4 = file.read(1).ord count = n2 | (n3 << 8) | (n4 << 16) end last_end_range += count * 256 cc = file.read(1).ord @ip_ranges.push(last_end_range) @country_codes.push(@country_table[cc]) end end end