您尚未提供示例数据。
你还没有告诉我们你是否真的知道你有“正确的”IPv6地址可以转换成IPv4。
但是,我们可以使用 base R 来实现基本算法:
ipv4_to_ipv6 <- function(x) {
sapply(x, function(res) {
res <- strsplit(res, ".", fixed=TRUE)[[1]]
res <- as.numeric(res)
res <- sprintf("%02x", res)
res <- toupper(sprintf("%s%s:%s%s", res[1], res[2], res[3], res[4]))
sprintf("2002:%s::%s", res, res)
}, USE.NAMES = FALSE)
}
ipv6_to_ipv4 <- function(x) {
sapply(x, function(res) {
res <- iptools::expand_ipv6(res) # NOTE: github version
res <- strsplit(res, ":", fixed=TRUE)[[1]]
res <- tail(res, 2)
res <- c( substr(res[1], 1, 2), substr(res[1], 3, 4), substr(res[2], 1, 2), substr(res[2], 3, 4))
res <- as.integer(as.raw(sprintf("0x%s", res)))
res <- paste0(res, collapse=".")
}, USE.NAMES = FALSE)
}
现在我将作弊并使用dplyr 中的方法来简化示例/测试代码:
set.seed(0)
dplyr::data_frame(
rip4_in = iptools::ip_random(10),
rip6 = ipv4_to_ipv6(rip4_in),
rip4_out = ipv6_to_ipv4(rip6)
)
## # A tibble: 10 x 3
## rip4_in rip6 rip4_out
## <chr> <chr> <chr>
## 1 113.251.221.104 2002:71FB:DD68::71FB:DD68 113.251.221.104
## 2 34.116.63.87 2002:2274:3F57::2274:3F57 34.116.63.87
## 3 47.227.58.127 2002:2FE3:3A7F::2FE3:3A7F 47.227.58.127
## 4 73.45.245.68 2002:492D:F544::492D:F544 73.45.245.68
## 5 115.111.38.132 2002:736F:2684::736F:2684 115.111.38.132
## 6 26.105.115.206 2002:1A69:73CE::1A69:73CE 26.105.115.206
## 7 114.50.117.41 2002:7232:7529::7232:7529 114.50.117.41
## 8 120.7.114.8 2002:7807:7208::7807:7208 120.7.114.8
## 9 84.66.177.142 2002:5442:B18E::5442:B18E 84.66.177.142
## 10 80.68.179.220 2002:5044:B3DC::5044:B3DC 80.68.179.220
注意:上面缺少 吨 对正确输入的验证检查。
另外:它们已被添加到 inet 包中。
阅读 — https://www.rfc-editor.org/rfc/rfc3056#section-2 — 了解其中的一些内容。
如果您拥有真实的“互联网”IPv4 和 IPv6 地址,并且试图将在同一系统上托管相同服务的主机与 IPv4 和 IPv6 客户端匹配,上述将无法正常工作。完成此操作的唯一方法是尝试到达您拥有的 A 或 AAAA 前面的 FQDN,然后查找您没有的 A 或 AAAA有。
该操作将花费 大量 时间来处理大量地址,因此我高度建议您创建一个本地缓存(SQLite 可能很好,具体取决于卷),因此您可以使用缓存检查来包装该查找舞蹈。