Reputation: 175
I have two tables. Table A contains 'ip_address' field and other table B which contains 'ip_start' and 'ip_end' (range of ip) along with other fields. I want to extract the details of ip_address from table B .
For example. Table A has
ip_address : '178.91.21.2"
Table B has
1. ip_start : "178.91.19.0" and ip_end : "178.91.19.255"
2. ip_start : "178.91.21.0" and ip_end : "178.91.21.255"
Now my query should return me the details associated with record 2 in table B.
I want achieve this in R. Can anybody suggest how it can be done?
Upvotes: 1
Views: 554
Reputation: 59415
Here's one way. The ipv4 addresses you specify are basically the decimal representation of 8-byte hex, so they can be represented as decimal integers simply by converting as below.
a.b.c.d = a × 2563 + b × 2562 + c × 256 + d
So we do this for both the test vector (ip
in this example), and the range data frame (ip.range
in this example) and then identify which range goes with which ip using simple arithmetic.
# example dataset
ip <- c("178.91.21.2","178.91.19.30","178.91.20.100")
ip.range <- data.frame(start=c("178.91.19.0", "178.91.20.0", "178.91.21.0"),
end= c("178.91.19.255","178.91.20.255","178.91.21.255"),
stringsAsFactors=FALSE)
# function to convert ip address to decimal integer
ip2integer <- function(ip) sapply(strsplit(ip,".",fixed=TRUE),function(x)sum(as.integer(x)*256^(3:0)))
# convert ip and ranges to integer
ip.int <- ip2integer(ip)
range.int <- data.frame(sapply(ip.range,ip2integer))
# find indices, combine into result
indx <- sapply(ip.int,function(x)with(range.int,which(x>=start & x <=end)))
result <- cbind(ip,ip.range[indx,])
result
# ip start end
# 3 178.91.21.2 178.91.21.0 178.91.21.255
# 1 178.91.19.30 178.91.19.0 178.91.19.255
# 2 178.91.20.100 178.91.20.0 178.91.20.255
Upvotes: 4