在lua中计算一个字节数组/用户数据的crc16校验和
我正在使用lua编写Wireshark协议解析器。该协议包含一个crc16校验和,解析器应检查crc是否正确。
我已经在CRC16实现代码中找到了一个已经用lua封装好的C语言写的crc16实现代码。我已经成功编译并运行它(例如:crc16.compute("test"))。问题在于它需要一个字符串作为输入。从Wireshark中得到的缓冲区似乎是lua类型的“userdata”。所以当我这样做时:
crc16.compute(buffer(5, 19))
Lua会抱怨“compute的错误参数#1(需要字符串,得到userdata)”。
CRC16实现代码中的compute()看起来像这样:
static int compute(lua_State *L)
{
const char *data;
size_t len = 0;
unsigned short r, crc = 0;
data = luaL_checklstring(L, 1, &len);
for ( ; len > 0; len--)
{
r = (unsigned short)(crc >> 8);
crc <<= 8;
crc ^= crc_table[r ^ *data];
data ++;
}
lua_pushinteger(L, crc);
return 1;
}
它似乎luaL_checklstring失败了。所以我猜我要么需要将输入转换为lua字符串,但我不确定它是否有效,因为我的输入并不一定是可打印字符。要么我需要调整上面的代码,使其接受类型为userdata的输入。我找到了lua_touserdata(),但这似乎返回类似指针的东西。所以我需要第二个参数表示长度,对吗?
我并不一定需要使用这个实现。任何能接受userdata的crc16实现代码都可以完美解决问题。
Christopher K 概括了大部分正确的答案,但将十六进制值转换回字节似乎有点难以实现。但是,我因为在寻找类似的东西而开始着手研究了。
遗漏的诀窍是不仅可以使用 buffer:bytes() 函数调用,还可以使用
buffer:raw()
这提供了所需的准确性:一个可以直接解析的简单 TSTRING,无需进行 ASCII 转换,我想这可能会显著增加 C 代码的负载。
- 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 代码?

你从wireshark中获得的缓冲区可以像这样用作ByteArray:
byte_array = Buffer(5,19):bytes();ByteArray有一个
_toString函数,它将字节转换为以十六进制表示的字符串。因此,您可以这样调用crc函数:crc16.compute(tostring(byte_array))“表示为十六进制的字节”意味着具有位
11111111的输入字节将转换为ASCII字符串FF。 ASCII字符串FF是01000110 01000110在位上,或者在十六进制中是46 46。这意味着在C中得到的并不是原始的字节数组。在计算crc之前,您需要将ASCII表示解码回原始字节,否则将显然得到不同的crc。 首先,该函数将包含一个ASCII十六进制字符的单个字符c转换回其表示的值:static char ascii2char(char c) { c = tolower(c); if(c >= '0' && c <= '9') return c - '0'; else if(c >= 'a' && c <= 'f') return c - 'a' + 10; }现在在计算函数中,我们遍历字符串表示,始终将两个字符组合成一个字节。
int compute(lua_State *L) { size_t len; const char * str = lua_tolstring(L, 1, &len); uint8_t * data = (uint8_t *) malloc(len/2); for(int n=0; n<len/2; n++) { data[n] = ascii2char(str[2*n]) << 4; data[n] |= ascii2char(str[2*n+1]); } crc16_t crc = crc16_init(); crc = crc16_update(crc, data, len/2); crc = crc16_finalize(crc); lua_pushinteger(L, crc); free(data); return 1; }在本例中,我使用了使用pycrc生成的crc函数
crc16_init,crc16_update和crc16_finalize,而不是问题中链接的crc实现。问题在于您需要使用与生成crc时相同的多项式等。 Pycrc允许你根据需要生成crc函数。 我的数据包还包含一个crc32。 Pycrc也可以为crc32生成代码,因此对于crc32,它可以按相同的方式工作。