1

I am returning an IP and then comparing it from a range.

I am just looking at the US IP and if it falls in a range I am displaying a messge. I am getting the IP correctly but when I am trying to match it with the range I am getting a syntax error of unexpected range. How should I resolve this?

here is how my code looks like

$.getJSON("http://jsonip.com", function (data) {
    var x = data.ip;
    $('body').html(x);

    var usRange = [3.0.0.0, 222.229.21.255];
    if (x >= usRange[0] && x <= usRange[1]) {
        alert('US');
    } else alert('outside US');
});

Here is my fiddle

Praveen
  • 55,303
  • 33
  • 133
  • 164
soum
  • 1,131
  • 3
  • 20
  • 47
  • And why do you think the built in javascript operators will work with IP adresses ? – adeneo Nov 30 '13 at 18:00
  • @adeneo--block the code line number 5 through 8 and you can see your IP. I dont understand what you are saying by the way..sorry – soum Nov 30 '13 at 18:02
  • You're missing curlybraces in the condition as well. – adeneo Nov 30 '13 at 18:05
  • 2
    And what I'm saying is that `3.0.0.0` isn't a valid number in javascript, so comparing it against, well anything, is going to fail. – adeneo Nov 30 '13 at 18:07
  • @adeneo--feel free to make corrections. Stackoverflow lets you do those type of things. If you have something to contribute to the question which you think would contribute to the solution feel free.-- Thanks – soum Nov 30 '13 at 18:08
  • 1
    You see, parsing IP adresses is complicated, it's not something I'll just whip up in a minute, and it's not something you can do with javascript operators, as a number (float) can only have one decimal, and IP adresses are invalid as number, they have to be strings, and then you have to build a parser to compare them. – adeneo Nov 30 '13 at 18:09
  • @adeneo--i see what you are saying – soum Nov 30 '13 at 18:11
  • 1
    Just check if you can do it with regex – sSaroj Nov 30 '13 at 18:18
  • @sSaroj--looks like that might work. – soum Nov 30 '13 at 18:20
  • 1
    why don't you just use an IP location service API that will tell you the country? – charlietfl Nov 30 '13 at 18:39
  • Consider http://freegeoip.net/ for geoip info – zamnuts Nov 30 '13 at 18:58

2 Answers2

3

What the error means, you can't assign number with 4 decimal dots.

var usRange = [3.0.0.0, 222.229.21.255]; //Not possible

FYI: The IP address returned from the json is string, not a number.

So you approach won't work. Here check my approach,

1) Split the ip address based on . returned by $.getJSON

var x = data.ip.split('.');  // returns ["122", "164", "17", "211"]

2) Instead of using usRange array just do it with simple comparison operations.

3) You cannot compare strings with numbers, so convert those strings to numbers like

+x[0] //convert "122" to 122

Finally,

$.getJSON("http://jsonip.com", function (data) {
    var x = data.ip.split('.');
    if (+x[0] >= 3 && +x[0] <= 222) {
        if (+x[1] >= 0 && +x[1] <= 229) {
            if (+x[2] >= 0 && +x[2] <= 21) {
                if (+x[3] >= 0 && +x[3] <= 255) {
                    alert("Within range");
                }
            }
        }
    } else {
        alert("Is not within range");
    }
});

JSFiddle

Praveen
  • 55,303
  • 33
  • 133
  • 164
3

I decided to rewrite my answer here for the sake of a better method. The first method actually converts the IP addresses to integers using bit shifting and then compares the integer values. I've left the second answer as an option but I prefer the first.

Neither of these functions will validate your IP addresses!

Method 1: Bit Shifting

/**
 * Checks if an IP address is within range of 2 other IP addresses
 * @param  {String}  ip         IP to validate
 * @param  {String}  lowerBound The lower bound of the range
 * @param  {String}  upperBound The upper bound of the range
 * @return {Boolean}            True or false
 */
function isWithinRange(ip, lowerBound, upperBound) {

  // Put all IPs into one array for iterating and split all into their own 
  // array of segments
  var ips = [ip.split('.'), lowerBound.split('.'), upperBound.split('.')];

  // Convert all IPs to ints
  for(var i = 0; i < ips.length; i++) {

    // Typecast all segments of all ips to ints
    for(var j = 0; j < ips[i].length; j++) {
      ips[i][j] = parseInt(ips[i][j]);
    }

    // Bit shift each segment to make it easier to compare
    ips[i] = 
      (ips[i][0] << 24) + 
      (ips[i][1] << 16) + 
      (ips[i][2] << 8) + 
      (ips[i][3]);
  }

  // Do comparisons
  if(ips[0] >= ips[1] && ips[0] <= ips[2]) return true;

  return false;
}

Method 2: Plain 'Ol Logic Mess

/**
 * Checks if an IP address is within range of 2 other IP addresses
 * @param  {String}  ip         IP to validate
 * @param  {String}  lowerBound The lower bound of the range
 * @param  {String}  upperBound The upper bound of the range
 * @return {Boolean}            True or false
 */
function isWithinRange(ip, lowerBound, upperBound) {

  // Save us some processing time if the IP equals either the lower bound or 
  // upper bound
  if (ip === lowerBound || ip === upperBound) return true;

  // Split IPs into arrays for iterations below. Use same variables since 
  // we won't need them as strings anymore and because someone will complain 
  // about wasting memory.
  ip = ip.split('.');
  lowerBound = lowerBound.split('.');
  upperBound = upperBound.split('.');

  // A nice, classic for loop iterating over each segment in the IP address
  for (var i = 0; i < 4; i++) {

    // We need those segments to be converted to ints or our comparisons 
    // will not work!
    ip[i] = parseInt(ip[i]);
    lowerBound[i] = parseInt(lowerBound[i]);
    upperBound[i] = parseInt(upperBound[i]);

    // If this is our first iteration, just make sure the first segment 
    // falls within or equal to the range values
    if (i === 0) {
      if (ip[i] < lowerBound[i] || ip[i] > upperBound[i]) {
        return false;
      }
    }

    // If the last segment was equal to the corresponding lower bound 
    // segment, make sure that the current segment is greater
    if (ip[i - 1] === lowerBound[i - 1]) {
      if (ip[i] < lowerBound[i]) return false;
    }

    // If the last segment was equal to the corresponding upper bound 
    // segment, make sure that the current segment is less than
    if (ip[i - 1] === upperBound[i - 1]) {
      if (ip[i] > upperBound[i]) return false;
    }
  }

  return true;
}
SaltedBlowfish
  • 105
  • 2
  • 9