为什么以下 Lua 代码是完全有效的?
从我的 Lua 知识(以及 Lua 手册中所述),我一直以来认为 Lua 中的标识符仅限于 A-Z、a-z、_ 和数字(不能以数字开头,也不能是保留关键字,即 local local = 123)。
现在我遇到了一些(混淆的)Lua 程序,它使用各种奇怪的字符作为标识符:
https://i.imgur.com/HPLKMxp.png
-- 可能无法复制粘贴。从 https://tknk.io/7HHZ 下载文件
print(_VERSION .. " " .. (jit and "JIT" or "non-JIT"))
local T = {}
T.math = T.math or {}
T.math.​â®â€‹âŞâ®â€‹ď»żâ€Śâ€âŽ = math.sin
T.math.â¬â€‹ââ¬ââ«â®â€â€¬ = math.cos
for k, v in pairs(T.math) do print(k, v) end
输出:
Lua 5.1 JIT
â¬â€‹ââ¬ââ«â®â€â€¬ function: builtin#45
​â®â€‹âŞâ®â€‹ď»żâ€Śâ€âŽ function: builtin#44
我不清楚为什么标识符允许使用这组字符?
换句话说,为什么它是一个完全有效的 Lua 程序?
与某些语言不同,Lua没有正式的规范来覆盖每个情况并完全解释Lua的所有行为。像“Lua文件编码是什么字符集”这样的简单问题在Lua的文档中并没有详细说明。
关于标识符的所有内容,文档中只有:
在Lua中,_名称_(也称为_标识符_)可以是任何由字母、数字和下划线组成的字符串,不以数字开头,也不是保留字。
但是,没有任何东西真正说明“字母”是什么。甚至还没有定义Lua使用什么字符集。因此,它基本上是取决于实现的。一个“字母”是......取决于实现需要什么。
所以,假设你正在编写一个Lua实现。你希望用户能够提供Unicode编码的字符串(也就是说,在Lua文本内的字符串)。Lua 5.3要求这样。但你也不希望它们必须使用UTF-16编码文件(也因为lua_load获得的是字节序列,而不是short)。因此,你的Lua实现假定lua_load得到的字节序列以UTF-8编码,以便用户可以编写使用Unicode字符的字符串。
当涉及到实现分析器的部分,你如何处理?处理UTF-8的最简单、最容易的方法是......不处理UTF-8。实际上,这就是该编码的整个意义所在。由于Lua定义的所有特定符号都是使用ASCII编码的,而ASCII文本也是具有相同含义的UTF-8文本,你可以将UTF-8字符串基本上看作ASCII字符串。对于Lua字符串,只需将字符串的开始和结束字符之间的字节序列复制即可。
那么,如何识别标识符?好吧,你可以问上面的问题。或者你可以问一个更简单的问题:这个字符是空格、控制字符、数字还是符号?一个“字母”只是一个不属于这些中的任何一个的东西。
Lua定义了它认为是“符号”的东西。ASCII可以告诉你哪些是控制字符、空格和数字。在这样的实现中,任何值在ASCII之外的UTF-8代码单元都是_字母_。即使从技术上讲,这些代码单元解码为Unicode认为是“符号”的东西,你的分词器也将其视为字母。
这种简单形式的UTF-8分析可提供快速的性能和低内存开销。你不需要将UTF-8解码为Unicode代码点,也不需要一个巨大的Unicode表来告诉你一个代码点是“符号”还是“空格”或其他类型。当然,它也是许多基于ASCII的Lua实现中自然获得的东西。
因此,大多数Lua实现都会这样做,即使只是偶然的结果。要做更多的事情需要有意识的努力。
它还允许用户使用Unicode字符序列作为标识符。这意味着某人可以轻松地用他们的母语编写代码(除了关键字)。
但它也意味着混淆器可以有很多方法来创建仅是无意义字节串的“标识符”。实际上,由于在Unicode中有多种“拼写”相同的Unicode字符串的方法(除非直接检查字节),混淆器可以搭配出看起来是相同文本的标识符,而实际上是不同的字符串。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的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 代码?

为了澄清,只有一个标识符
T。T.math是T["math"]的糖语法,这也适用于混淆的字符串。拥有包含任何字符或以数字开头的“键”是完全有效的。现在能够使用
.而不是[ ]与不符合标识符限制的字符串无法使用。请查看Nicol Bolas的答案以了解这些限制的详细分析。