具有校验和功能的功能产生nACK响应

时间:2015-12-08 21:33:54

标签: lua checksum

对于我目前的应用程序,我正在编写一个允许设备与从设备通话的插件。从设备有两个校验和,一个头和一个数据校验和。标题校验和产生了一些不稳定的结果,这些结果经过精心调整并由成员在此处更正:Odd Checksum Result(s) - Not Receiving Expected Results

现在我不确定我的数据校验和是否正确。我相信这是因为我在这里创建的一个帖子来帮助理解和构建它,我在这里做了: Converting a C Checksum Function to Lua

现在,我不认为这是数据校验和功能。但我相信这是我试图实现它的方式。我现在正在尝试复制示例代码并将其发送到我的从设备,希望我收到相应的响应。问题是我收到了nACK的回报。我已经尝试了我能想到的每一种排列和组合,而且我没有收到可接受的价值。 input表示我需要发送到下面function databuild(str)函数的字符串。

input = "010032380000000000000000000000000000000000000000"  -- title must be a specific length so it is filled with NUL's to meet that criteria

function CRC(data, length)
    sum = 65535
    local d
    for i = 1, length do
        d = string.byte(data, i)
        sum = ByteCRC(sum, d)
    end
    return sum
end

function ByteCRC(sum, data)
    sum = sum ~ data
    for i = 0, 7 do
        if ((sum & 1) == 0) then
            sum = sum >> 1
        else
            sum = (sum >> 1) ~ 0xA001
        end
    end
    return sum
end

function databuild(str) -- I know I should not be doing what's inside here but don't fully understand why not to and better ways of approaching it.
    local dataSum = ""
    local dataSumReslt = ""
    local dataConv = ""
    for char in str:gmatch("..") do
        dataConv = dataConv..string.char("0x"..char)
    end
    dataSum = string.format("%04X", CRC(dataConv, #dataConv))
    for char in dataSum:gmatch("..") do
        dataSumReslt = dataSumReslt..string.char("0x"..char)
    end
    return dataConv..dataSumReslt
end

print(databuild(input))

我应该根据print语句中的那些字节值来获取数据校验和。我将整个字符串发送到function databuild(str)函数。从那里我将结果转换为十六进制格式,然后连接该结果(通过string.char将双字节值转换为十六进制)然后返回整个十六进制字符串。

现在,实际上,我得到了结果170B。不幸的是,我在编程方面不够先进,无法正确调试或测试我收到的内容是否属实。

  • 我应该在执行function CRC(data, length)之前先将数据字符串转换为十六进制,还是先将十进制表示保留为十六进制表示,或者甚至是否重要?

  • 由于我的文件中的所有2字节和4字节字都需要是little-endian,这是否意味着我的校验和也应该是little-endian?或者校验和是否保持不变? (校验和功能在从设备手册的C中提供。

  • 最后,有什么更好的方法来接近function databuild(str),这样我就不会分解每个字节,翻译它,然后将它连接起来呢?我的代码得到纠正后,我非常感激。但有人可以帮我理解为什么这不是一件好事吗?

由于我对编程很新,所以大部分时间我都没有尝试在这个低级别(位操作)工作。我的任何课程都没有达到这一点,因为它是所有高级程序设计(Java和自学成才,我在Lua中知道)。这是我的第一个工作项目,它真正的“火灾洗礼”涉及字节,十六进制转换等。不用说,我几乎没有把头放在水面上。所以我得到的所有建设性批评都是绝对的。

2 个答案:

答案 0 :(得分:2)

您可以替换

for char in str:gmatch("..") do
    dataConv = dataConv..string.char("0x"..char)
end

dataConv = str:gsub("..",function (x) return string.char(tonumber(x,16)) end)

您可以将此简化为

dataConv = str:gsub("..",HEX)

完成后

HEX={}
for c=0,255 do
    HEX[string.format("%02x",c)] = string.char(c)
end

这样可以避免连接。

答案 1 :(得分:0)

嗨,您在MarkemImaje打印机上遇到了问题。

您在这里有一个错误:

sum = (sum >> 1) ~ 0xA001 --> sum = (sum >> 1) ^ 0xA001