当前位置: 首页 > 知识库问答 >
问题:

在lua中计算bytearray/userdata的crc16

鲜于河
2023-03-14

我正在用Lua编写一个Wireshark协议解析器。它解析的协议包含crc16校验和。解剖者应检查crc是否正确。

我在这里发现了一个用C编写的crc16实现,其中已经包含了lua包装器代码。我已经成功编译并运行了它(例如crc16.compute(“test”))。问题是它需要一个字符串作为输入。从wireshark中,我得到了一个似乎是lua类型userdata的缓冲区。所以当我这么做的时候

crc16.compute(buffer(5, 19))

Lua抱怨计算错误的参数#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;
}

共有1个答案

轩辕成天
2023-03-14

从wireshark获得的缓冲区可以用作字节数组,如下所示:

byte_array = Buffer(5,19):bytes();

ByteArray有一个_tostring函数,用于将字节转换为表示为十六进制的字节的字符串表示形式。所以可以像这样调用crc函数:

crc16.compute(tostring(byte_array))

“表示为十六进制的字节的表示”意味着具有11111111位的输入字节将转换为ASCII字符串FF。ASCII字符串ff0100011001000110(位)或4646(十六进制)。这意味着你在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;
}

现在,在compute函数中,我们循环遍历字符串表示,总是将两个字符合并成一个字节。

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_initcrc16_updatecrc16_finalize,而不是问题中链接的crc实现。问题是您需要使用与生成CRC时相同的多边形等。Pycrc允许您根据需要生成crc函数。我的包还包含一个CRC32。Pycrc还可以为crc32生成代码,因此它对crc32的工作方式是一样的。

 类似资料:
  • 问题内容: 我需要传递给jqgrid,但找不到如何执行此操作的任何示例。这是我的尝试: 从服务器发送: 并在jqgrid中: 如何从jqgrid 发送和阅读? 编辑:我知道我正在被发送,因为我可以在Fiddler中看到它。我认为我只是停留在如何在客户端上阅读它。 问题答案: 通常,的用法非常简单。jqGrid支持您从服务器发送 将与jqGrid数据一起保存的 任何其他 数据。所以,如果jqGrid

  • 主要内容:算术运算符,实例,实例,关系运算符,实例,逻辑运算符,实例,其他运算符,实例,运算符优先级,实例运算符是一个特殊的符号,用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型: 算术运算符 关系运算符 逻辑运算符 其他运算符 算术运算符 下表列出了 Lua 语言中的常用算术运算符,设定 A 的值为10,B 的值为 20: 操作符 描述 实例 + 加法 A + B 输出结果 30 - 减法 A - B 输出结果 -10 * 乘法 A * B 输出结果 200 / 除法 B

  • 运算符是一个特殊的符号,用于告诉解释器执行特定的数学或逻辑运算。Lua提供了以下几种运算符类型: 算术运算符 关系运算符 逻辑运算符 其他运算符 算术运算符 下表列出了 Lua 语言中的常用算术运算符,设定 A 的值为10,B 的值为 20: 操作符 描述 实例 + 加法 A + B 输出结果 30 - 减法 A - B 输出结果 -10 * 乘法 A * B 输出结果 200 / 除法 B /

  • 问题内容: 我有这个MySQL查询: 返回如下内容: 我真正想要的是末尾的另一列显示运行总计: 这可能吗? 问题答案: 也许这对您来说是一个更简单的解决方案,并且可以防止数据库不得不执行大量查询。这仅执行一个查询,然后在一次通过中对结果进行一点数学运算。 这将为您提供一个额外的RT(运行总计)列。不要错过顶部的SET语句来首先初始化运行的total变量,否则您将只获得一列NULL值。

  • 问题内容: 我一直在阅读neo4j及其组件的文档,但尚未遇到可让我查询图中的基元总数(节点,关系和属性)的功能。此功能是否存在于某个地方?还是我必须编写遍历整个图形的代码? 问题答案: 谢谢你的提问!我在Neo4j团队中工作,目前我们有报告此类信息的商业工具。但是,API的扩展已计划用于下一个开源版本。目前,您可以使用以下非官方API: 所在班级会,或。

  • 问题内容: 我在Eclipse中有一个Java项目,每个程序包有大约10个包和10个类文件。有没有办法从Eclipse中确定整个项目的总代码行?我熟悉其他工具(例如,代码分析器,wc等),但是我想知道Eclipse中是否有办法(或者确认没有办法)。 问题答案: 这是一个很好的指标插件,可以显示代码行数以及更多内容: http://metrics.sourceforge.net/ 它说它需要Ecli