将IPv4地址拆分为最小和最大范围。
2014-2-11 14:22:26
收藏:0
阅读:151
评论:2
使用Lua如何拆分给定的IP地址,以获取最小和最大范围,例如:
94.19.21.119
我有一个像这样的CSV:
18087936,18153471,“AU”
18153472,18219007,“JP”
18219008,18350079,“IN”
18350080,18874367,“CN”
已读取为3个表并且csv是min,max,country code:
IPfrom = {}
IPto = {}
IPCountry = {}
它们像这样被填充:
IPfrom [18087936] = L
IPto [L] = 18153471
IPCountry [L] =“AU”
其中L是io.read的行号,然后我尝试获取最小范围,以便我可以在不循环的情况下检查是否存在,然后如果它存在,该键将保存最大范围的索引,如果IP在最小/最大范围内,那么我获取国家代码。可能有一种不同的做事方式,但表中有超过100,000个条目,因此循环需要一些时间。
点赞
用户869951
哈希表(Lua的基本类型)会给你 O(N) 的时间复杂度。没有空洞且索引从 someMinAddr 到 someMaxAddr 的数组(一种表)会给你 O(1) 的时间复杂度,但会使用相当多的内存。通过适当地排序结构化表进行二分查找,可以给你 O(log N) 的时间复杂度,对于 100000 个地址来说,这可能值得付出努力。我想你可以使用这样的结构:
IPfrom = {
{line=L1, addFrom=from1, addrTo=to1, c=country1},
{line=L2, addFrom=from2, addrTo=to2, c=country2},
{line=L3, addFrom=from3, addrTo=to3, c=country3},
{line=L4, addFrom=from4, addrTo=to4, c=country4},
...
}
因为我没看到将to和country字段与其他信息分开的意义,这只会增加表查找的次数。无论如何,如果你真的想把它们分开,下面的代码不会受到影响:
-- 初始化:
从 CSV 文件创建表
对 IPFrom 中的 addFrom 字段进行排序
-- 需要多少次就执行多少次:
function findIP(addr)
addr 是否小于 IPfrom[middle].addrTo3?
如果是,addr 是否小于 IPfrom[middle of middle]?
等等
end
这是递归的,所以如果你将其结构化得当,可以使用尾递归,并不担心栈溢出 (;),类似这样:
function findIPRecurs(addr, ipTbl, indxMin, indxMax)
local middle = (indxMin + indxMax )/2
local midAddr = ipTbl[middle].addrFrom
if addr < midAddr then
return findIPRecurs(addr, ipTbl, indxMin, middle)
else if addr > midAddr then
return findIPRecurs(addr, ipTbl, middle, indxMax)
else -- 有条目:
return middle
end
end
function findIP(addr)
return findIPRecurs(addr, ipTbl, 1, #ipTbl)
end
我没有测试过,所以可能还需要修整,但你可以理解这个思路。这将使用与 O(N) 方法相同的内存,但对于大型数组来说,速度会快得多;比 O(1) 方法少得多的内存,并且可能可以接受更慢的速度。
2014-02-11 21:09:10
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
也许以下代码对你有用:
-- -- 将IPv4地址转化为整数值 -- function iptoint(ip) local ipint = 0 local iter = string.gmatch(ip, "%d+") for i = 3, 0, -1 do local piece = tonumber(iter()) if piece == nil or piece < 0 or piece > 255 then return nil end ipint = bit32.bor(ipint, bit32.lshift(piece, 8 * i)) end return ipint end -- -- 在一个多维表中查找IPv4地址,表中的条目为: -- {start_address, end_address, country} -- 然后返回匹配的国家 -- function iptocountry(ip, tbl) local ipint = iptoint(ip) if ipint == nil then return nil end for _,v in pairs(tbl) do if ipint >= v[1] and ipint <= v[2] then return v[3] end end return nil end用法示例:
local countries = { {16777216, 17367039, "US"}, {1578300000, 1678300000, "CAN"} -- ... 从CSV文件中加载其他条目 } local ip = "94.19.21.119" print (iptocountry(ip, countries)) -- 输出CAN