对于我目前的应用程序,我正在编写一个允许设备与从设备通话的插件。从设备有两个校验和,一个头和一个数据校验和。标题校验和产生了一些不稳定的结果,这些结果经过精心调整并由成员在此处更正: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中知道)。这是我的第一个工作项目,它真正的“火灾洗礼”涉及字节,十六进制转换等。不用说,我几乎没有把头放在水面上。所以我得到的所有建设性批评都是绝对的。
答案 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