Find distance between 2 IPs using BASH

In this tutorial, we will show how to calculate the distance between 2 IPs using geographical coordinates provided by any IP2Location database, except DB1, DB2, DB3, DB3 and DB7, as you can see at http://www.ip2location.com/databases

The programming language for this tutorial is BASH and you have to know a little scripting. The prerequisites for running this tutorial are:

This tutorial has four steps for implementing the BASH script, that calculates the distance between 2 IPs and one for testing.

 

Step 1. For the beginning of this tutorial, we will start by showing you how to calculate the distance between any 2 points knowing the latitude and longitude of the points. The formula uses The Spherical Law of Cosines, because nowadays, float is very precise. The formula for this task is the following: (The code is taken from http://www.movable-type.co.uk/scripts/latlong.html).

R = 6371; // km
distance = Math.acos(Math.sin(lat1)*Math.sin(lat2) +
				  Math.cos(lat1)*Math.cos(lat2) *
				  Math.cos(lon2-lon1)) * R;

 

Step 2. We can implement this formula in Bash in the following way using bc: (bc is a precision calculator language)

EARTH_RADIUS="6371"
PI="3.141592653589793"

#Converts degrees in radians (
deg2rad() {
        bc -l <<< "$1 * $PI / 180"
}

#Converts radians in degrees
rad2deg()  {
        bc -l <<< "$1 * 180 / $PI"
}

#Calculates acos($radians), because bc has no acos function
acos()  {
        bc -l <<<"$PI / 2 - a($1 / sqrt(1 - $1 * $1))"
}

#Applies The Spherical Law of Cosines for finding distance between 2 coordinates
getDistance() {

	delta_lat=$(bc <<<"$LAT2 - $LAT1")
	delta_lon=$(bc <<<"$LONG2 - $LONG1")
	LAT1=$(deg2rad "$LAT1")
	LONG1=$(deg2rad "$LONG1")
	LAT2=$(deg2rad "$LAT2")
	LONG2=$(deg2rad "$LONG2")
	delta_lat=$(deg2rad "$delta_lat")
	delta_lon=$(deg2rad "$delta_lon")

	DISTANCE=$(bc -l <<< "s($LAT1) * s($LAT2) + c($LAT1) * c($LAT2) * c($delta_lon)")

	DISTANCE=$(acos "$DISTANCE")
	DISTANCE=$(bc -l <<< "$DISTANCE * $EARTH_RADIUS")
	DISTANCE=$(bc <<<"scale=4; $DISTANCE / 1")
}

 

Step 3. In this step, we will show how to combine the simple demo program with the BASH script and how to find the distance between two IPs, which is the goal of this tutorial. For this step, we must parse the output of ip2locationLatLong program with cut.

#!/bin/bash

#This is the location of bin file
#You must modify for your system
BIN_FILE="db5.bin"


EARTH_RADIUS="6371"
PI="3.141592653589793"

#Converts degrees in radians (
deg2rad() {
        bc -l <<< "$1 * $PI / 180"
}

#Converts radians in degrees
rad2deg()  {
        bc -l <<< "$1 * 180 / $PI"
}

#Calculates acos($radians), because bc has no acos function
acos()  {
        bc -l <<<"$PI / 2 - a($1 / sqrt(1 - $1 * $1))"
}

#Applies The Spherical Law of Cosines for finding distance between 2 coordinates
getDistance() {

	delta_lat=$(bc <<<"$LAT2 - $LAT1")
	delta_lon=$(bc <<<"$LONG2 - $LONG1")
	LAT1=$(deg2rad "$LAT1")
	LONG1=$(deg2rad "$LONG1")
	LAT2=$(deg2rad "$LAT2")
	LONG2=$(deg2rad "$LONG2")
	delta_lat=$(deg2rad "$delta_lat")
	delta_lon=$(deg2rad "$delta_lon")

	DISTANCE=$(bc -l <<< "s($LAT1) * s($LAT2) + c($LAT1) * c($LAT2) * c($delta_lon)")

	DISTANCE=$(acos "$DISTANCE")
	DISTANCE=$(bc -l <<< "$DISTANCE * $EARTH_RADIUS")
	DISTANCE=$(bc <<<"scale=4; $DISTANCE / 1")
}

#Retrieves the coordinates for the 2 IPs
getCoordinate()
{
	#Call ip2locationLatLong for $IP1
	output=$(./ip2locationLatLong "$BIN_FILE" "$IP1")

	#Parse the output to obtain both coordinates
	LAT1=$(echo "$output" | cut -d ',' -f 1)
	LONG1=$(echo "$output" | cut -d ',' -f 2)

	#Call ip2locationLatLong for $IP2
	output=$(./ip2locationLatLong "$BIN_FILE" "$IP2")

	#Parse the output to obtain both coordinates
	LAT2=$(echo "$output" | cut -d ',' -f 1)
	LONG2=$(echo "$output" | cut -d ',' -f 2)
}

#Prints the coordinates for the 2 IPs
printCoordinate()
{
	echo "Coordinates for $IP1: ($LAT1,$LONG1)"
	echo "Coordinates for $IP2: ($LAT2,$LONG2)"
}

#Checks if the coordinates are not empty
validCoord()
{
	ip=$1
	coord=$2

	if [ "$coord" = "" ]; then
		echo "$ip is not a good address"
		exit 0
	fi
}

#Checks if the script is run with 2 parameters
if [ $# -ne 2 ]; then
	echo "Usage: $(basename $0) IP1 IP2"
	exit 0;
fi

IP1=$1
IP2=$2

#Retrieves and validates the coordinates
getCoordinate
printCoordinate
validCoord $IP1 $LAT1
validCoord $IP1 $LONG1
validCoord $IP2 $LAT2
validCoord $IP2 $LONG2

#Calculate and print the distance
getDistance
echo "Distance between $IP1 and $IP2 is $DISTANCE km"

 

Step 4. You can now run the script.

bash getDistance.sh 89.89.89.89 30.13.56.34

 

Step 5. You can validate the output distance running the script from http://www.movable-type.co.uk/scripts/latlong.html which calculates the distance between two points.


Do you like this article? Share it with others by clicking the social media buttons below. We will write more articles related to this topic.