将IP地址(IPv4)转换为整数在R中

4
我在寻找一种在R中编写函数的方法,将IP地址转换为整数。
我的数据框长这样:
total  IP
626    189.14.153.147
510    67.201.11.8
509    64.22.53.140
483    180.9.85.10
403    98.8.136.126
391    64.06.187.68

我从mysql数据库导出了这些数据。我有一个查询,可以将IP地址在mysql中转换为整数:

mysql> select CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 1), '.', -1) << 24 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 2), '.', -1) << 16 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 3), '.', -1) << 8 AS UNSIGNED) + CAST(SUBSTRING_INDEX(SUBSTRING_INDEX('75.19.168.155', '.', 4), '.', -1) AS UNSIGNED) FINAL;

但我想在R中进行此转换,任何帮助都将是极好的。


为什么不使用 INET6_ATON() / INET_ATON(),然后直接使用原始整数呢? - BlitZ
1个回答

6

由于您的需求不是非常明确,所以我将十进制数值乘以了一个我认为合适的值(考虑到这些三位数相当于“256进制”数字的十进制表示法,然后再在十进制下重新显示)。如果您想要位置的顺序反转,如其他地方建议的那样,您需要在两种解决方法中反转'vals'的索引。

 convIP <- function(IP) { vals <- read.table(text=as.character(IP), sep=".")
               return( vals[1] + 256*vals[2] + 256^2*vals[3] + 256^3*vals[4]) }

> convIP(dat$IP)
          V1
1 2476281533
2  134990147
3 2352289344
4  173345204
5 2122844258
6 1153107520

通常更好的IT实践是指定您认为是正确答案的内容,以便进行测试。Bertelson上面的评论将更快,并隐含使用1000、1000^2和1000^3作为因子。

我正在尝试简化代码,但担心需要使用Reduce("+", ...)可能会使它更复杂。您不能使用sum,因为它不是向量化的。

 convIP <- function(IP) { vals <- read.table(text=as.character(IP), sep=".")
                return( Reduce("+", vals*256^(3:0))) }

> convIP(dat$IP)
[1] 5737849088    5112017 2717938944    1245449 3925902848   16449610

2
非常感谢,这正是我想要的,同时对我的表述不够清晰表示歉意。本质上,这是我的主要目标 convIP <- function(IP) { vals <- read.table(text=as.character(IP), sep=".")
  • return( 256^3*vals[1] + 256^2*vals[2] + 256*vals[3] + vals[4]) }
- user3006691
哎呀。我猜我倒置了乘法的顺序。 - IRTFM
但我不理解Bertelsen的命令如何工作?@IShouldBuyABoat - user3006691
他会将1.1.0.1转换为1101。所以你是对的。除非他将小于3位小数的数字扩展到正确的前导0数量,否则它实际上无法提供唯一值。即使进行了这种修改,结果值仍然存在很多间隙。 - IRTFM
谢谢你提供的Reduce代码,我可以用它来做其他事情。@IShouldBuyABoat - user3006691

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接