我有一个通过 RS232 控制的 Athena 16C Controller 。它的消息传递协议(protocol)需要专有校验和:
"CHKSUM:这是一个双字符消息代码编号系统,表示消息中所有字符(不包括 START、CHAR、END CHAR 和 CHKSM 本身)的所有 ASCII 值的总和。总和使用以下公式计算: CHKSM = SUM(All Message Characters)%256 其中 % 代表取模运算符。"
一个示例消息(来自他们的文档)是这样的:
$Ø1Ø1RØ5C1<CR>
可以分解为:
$ [START CHAR] 01 [ID] 01 [ZONE] R [TYPE] 05 [PARAM] C1 [CHKSM] <CR> [END CHAR]
我已将此消息发送给 Controller ,它按预期工作。
我正在用 JS 编写我的代码,并且有以下应该计算 CHKSM 的信息放在消息的末尾:
var sum = 'Ø1Ø1RØ5'
.split('')
.map(function(char) {
return char.charCodeAt(0);
})
.reduce(function(current, previous) {
return previous + current;
});
var chksm = (sum % 256);
console.log(chksm.toString(16));
根据消息格式,校验和应为“C1”。但是计算出的总和是 377,这导致校验和为 121,等于十六进制的 79。
// 0 = 48, 1 = 49, R = 82, 5 = 53 (ASCII values)
// 48 + 49 + 48 + 49 + 82 + 48 + 53 = 377
// 377 % 256 = 121 (decimal) = 79 (hex)
Athena 的一位工程师向我发送了以下 VB 代码,但我无法理解其中的逻辑,尤其是语法。一般而言,这个问题是否缺少一些基本的东西?
' Covert the mod % 256 checksum to the 2 chars:
' Will set First and Second chars for encoded value. Pass in the value (Checksum mod 256)
' and where to return the 1st and 2nd chars to.
Public Sub EncodeIt(ByVal Value As Integer, ByRef FirstChar As Integer, ByRef SecondChar As Integer)
If Value > 359 Then 'Z9 = 359, absolute max possible
Value = 359
End If
'Note: backslash '\' means integer divide, not floating point!!
If Value > 99 Then
FirstChar = (Value \ 10) + 65 - 10 '65 = ascii "A"
Else
FirstChar = (Value \ 10) + 48 '48 = ascii "0"
End If
SecondChar = (Value Mod 10) + 48
End Sub
' Convert the two chars received in a message back to normal integer.
' Take the 2 chars and return a decoded integer value
Public Function DecodeIt(ByVal FirstChar As Integer, ByVal SecondChar As Integer) As Integer
'65 = ascii "A", 48 = ascii "0"
If FirstChar > 57 Then '57 = ascii "9"
Return ((FirstChar - 65 + 10) * 10) + (SecondChar - 48)
Else
Return ((FirstChar - 48) * 10) + (SecondChar - 48)
End If
End Function
最佳答案
从十进制到字符串的编码是自定义的,而不是 base16。这就是为什么 (121).toString(16)
不等于 C1
的原因。
从您帖子的 VBA 中,编码/解码函数应该是:
function compute_checksum(message) {
var sum = 0;
for(var i=0; i<message.length; i++)
sum += message.charCodeAt(i);
return sum % 256;
}
function encode_checksum(value) {
value = Math.min(value, 359);
var c1 = ((value / 10) | 0) + (value > 99 ? 55 : 48);
var c2 = (value % 10) + 48;
return String.fromCharCode(c1, c2);
}
function decode_checksum(text) {
var c1 = text.charCodeAt(0);
var c2 = text.charCodeAt(1);
return (c1 > 57 ? c1 - 55 : c1 - 48) * 10 + (c2 - 48)
}
这是一个用法示例:
var checksum = compute_checksum('0101R05');
console.log('checksum: ' + checksum);
var CHKSM = encode_checksum(checksum);
console.log('encoded checksum: ' + CHKSM);
console.log('decoded checksum: ' + decode_checksum(CHKSM));
关于javascript - 我如何编码/解码这个专有校验和(Athena 16C PID Controller )?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37084302/