javascript - 我如何编码/解码这个专有校验和(Athena 16C PID Controller )?

标签 javascript vba serial-port protocols checksum

我有一个通过 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/

相关文章:

java - Android,使用库还是复制源代码?

go - 如何正确使用同步机制从串口读取输入

javascript - case user.length < 4;控制台日志 ("nametoo short :(");休息;为什么这不起作用?

VBA 将 anchor (超链接)添加到事件工作表

Excel 2010 - 单元格和形状着色 - 我的想法

excel - VBA复制一个值后加 "+"

来自 Com 端口的 Java readLine

javascript - 检查js函数中未定义的参数

javascript - 根据客户的语言向正文添加类

javascript - 从 Angular Directive(指令)调用父 Controller 的功能