# Re: IP to Country (#139)

**URL:** <https://www.ruby-forum.com/t/re-ip-to-country-139/114739>\
**Category:** Ruby\
**Created:** [September 17, 2007, 1:24pm UTC](https://www.ruby-forum.com/t/re-ip-to-country-139/114739 "2007-09-17T13:24:59Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![steve\_d](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ce73a5/32.png) [@steve\_d](https://www.ruby-forum.com/u/steve_d)\
**Post date:** [September 17, 2007, 1:24pm UTC](https://www.ruby-forum.com/t/re-ip-to-country-139/114739/1 "2007-09-17T13:24:59Z")

</div>

On 9/14/07, Ruby Q. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> This week’s Ruby Q. 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  
> at:
> 
> ```
> http://software77.net/cgi-bin/ip-country/geo-ip.pl
> 
> ```
> 
> To keep the problem interesting though, let’s write our programs with a focus on  
> speed and memory efficiency.

Hi All,

Here’s my submission. It’s almost exactly the same as Jesus’. I have  
a feeling everyone is going to have very similar code for this one.

[http://pastie.caboo.se/97332](http://pastie.caboo.se/97332)  
os = ARGV[0].split(/./)  
ip = os[3].to\_i + os[2].to\_i_256 + os[1].to\_i_256**2 + os[0].to\_i\*256**3

f = File.open(“IpToCountry.csv”)

# perform binary search on the file

low = 0  
high = f.stat.size

while low \<= high  
mid = (low + high) / 2

f.seek mid # seek to the middle of our search window  
f.seek -2, IO::SEEK\_CUR until f.getc == ?\n # walk backwards until  
we hit a newline

new\_high = f.pos - 1  
line = f.gets  
new\_low = f.pos

from, to, x, x, country = line[1…-1].split(/“,”/)

if to.to\_i \< ip # we are too low, set new low to after this line  
low = new\_low  
elsif from.to\_i \> ip # we are too high, set new high to before the  
last newline  
high = new\_high  
else  
puts country; exit  
end  
end

puts “no country”- steve
