Skip to content

Instantly share code, notes, and snippets.

@tristanstraub
Created August 1, 2014 06:22
Show Gist options
  • Save tristanstraub/6b4cfec3defc9f150f53 to your computer and use it in GitHub Desktop.
Save tristanstraub/6b4cfec3defc9f150f53 to your computer and use it in GitHub Desktop.
fs = require 'fs'
GEO_FIELD_MIN = 0
GEO_FIELD_MAX = 1
GEO_FIELD_COUNTRY = 2
exports.ip2long = (ip) ->
ip = ip.split '.', 4
return +ip[0] * 16777216 + +ip[1] * 65536 + +ip[2] * 256 + +ip[3]
gindex = []
exports.load = ->
data = fs.readFileSync "#{__dirname}/../data/geo.txt", 'utf8'
data = data.toString().split '\n'
for line in data when line
line = line.split '\t'
# GEO_FIELD_MIN, GEO_FIELD_MAX, GEO_FIELD_COUNTRY
gindex.push [+line[0], +line[1], line[3]]
gindex.sort (x, y) -> x[GEO_FIELD_MIN] - y[GEO_FIELD_MIN]
normalize = (row) -> country: row[GEO_FIELD_COUNTRY]
exports.lookup = (ip) ->
return -1 unless ip
find = this.ip2long ip
bottom = 0
top = gindex.length
#invariant find >= line[GEO_FIELD_MIN]
# find <= line[GEO_FIELD_MAX]
while bottom < top - 1
middle = Math.floor(bottom + (top - bottom)/2)
line = gindex[middle]
if find > line[GEO_FIELD_MAX]
bottom = middle
else
top = middle
if find >= line[GEO_FIELD_MIN] and find <= line[GEO_FIELD_MAX]
return normalize line
return null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment