Begin forwarded message: > From: "Adam Shelly" <adam.shelly / gmail.com> > Date: September 15, 2007 3:27:43 AM CDT > To: submission / rubyquiz.com > Subject: Re: [QUIZ] IP to Country (#139) - early submission, please > forward after deadline > > On 9/14/07, Ruby Quiz <james / grayproductions.net> wrote: >> This week's Ruby Quiz is to write a simple utility. Your program >> should accept >> an IP address as a command-line argument and print out the two >> letter code for >> the country that IP is assigned in. You can find a database for >> the matching > > Hi James, > I'm going to be offline for the next few days, so please accept my > early submission to forward after the deadline. > Thanks, > -Adam. > > ------------------------------- > > Here's my quickly created version that works off the unmodified file > without any initialization. > > --- IpToCountry.rb -- > > #Use this function to find the first and last record of the file. > #I ran this once and hardcoded the values in order to improve > execution time > #It was run against file dated Fri Sep 14 12:08:01 2007 UTC. > #It should be run again if the database changes > > def find_valid_data filename > start = 0 > dbfile = File.new(filename) > s = dbfile.gets > while s[0] == ?# or s[0]==?\n > start+= s.size > s = dbfile.gets > end > dbfile.seek(-128, File::SEEK_END) > s = dbfile.read(128).chomp; > last = s.rindex("\n"); > dbfile.close > return [start-1,File.size(filename) - last] > end > > > def addr_to_i addr > radix = 256**4 > addr.split('.').inject(0){|sum,part| sum + part.to_i * (radix / > =256)} > end > > > def bsearch_file value, min, max > return "Not Found" if max<=min > point = (max-min)/2 + min > DBFile.seek(point-1, File::SEEK_SET) > DBFile.gets #get partial line > line = DBFile.gets > rec = line.split('"') > range = (rec[1].to_i .. rec[3].to_i) > #puts "searching #{point}: range = (#{range})" > return rec[9] if range.include? value > if value < range.first > #p "lower" > return bsearch_file(value, min, point-2) > else > #p "higher" > return bsearch_file(value,point+line.size,max) > end > end > > > DBFilename = "IpToCountry.csv" > # > # datarange = find_valid_data DBFilename > # > datarange = [6604,5788762] > > DBFile = File.new(DBFilename) > > addr_n = addr_to_i(ARGV[0]||"123.45.67.89") > puts bsearch_file(addr_n, *datarange)