Javascript中的纵向冗余检查

我正在使用集成销售点(POS)设备的系统,我使用chrome串口扫描端口并能够读取信用卡数据。

我面临的问题是我需要从这个格式的string连接LRC:

STX ='\ 002'(2 HEX)(文本开始)

LLL =数据长度(不包括STX或ETX,但命令)。

Command C50 {C =从PC到POS的消息,50在POS上“打印”消息的实际代码}

ETX ='\ 003'(3 HEX)(文本结尾)

LRC = 纵向冗余检查

消息示例如下:

'\002014C50HELLO WORLD\003'

这里我们可以看到002为STX,014是从C50到D的长度,003是ETX。

我在C#中find了这样一个或者这个 ,甚至是Java中的一些algorithm,我甚至在Google的caching中看到了从SO上移除的这个问题 , 这个问题其实和我一样问,但没有例子或答案。

我也做了这个Javaalgorithm:

 private int calculateLRC(String str) { int result = 0; for (int i = 0; i < str.length(); i++) { String char1 = str.substring(i, i + 1); char[] char2 = char1.toCharArray(); int number = char2[0]; result = result ^ number; } return result; } 

并尝试将其传递给Javascript(我知之甚less)

 function calculateLRC2(str) { var result = 0; for (var i = 0; i < str.length; i++) { var char1 = str.substring(i, i + 1); //var char2[] = char1.join(''); var number = char1; result = result ^ number; } return result.toString(); } 

并遵循维基百科的伪代码,我试着这样做:

 function calculateLRC(str) { var buffer = convertStringToArrayBuffer(str); var lrc; for (var i = 0; i < str.length; i++) { lrc = (lrc + buffer[i]) & 0xFF; } lrc = ((lrc ^ 0xFF) + 1) & 0xFF; return lrc; } 

这就是我所说的上述方法:

 var finalMessage = '\002014C50HELLO WORLD\003' var lrc = calculateLRC(finalMessage); console.log('lrc: ' + lrc); finalMessage = finalMessage.concat(lrc); console.log('finalMessage: ' + finalMessage); 

但是,尝试所有这些方法后,我仍然无法正确地向POS发送消息。 我现在有3天的时间试图解决这个问题,除非完成,否则不能做任何事情。

有没有人知道另一种方式来计算LRC或我在这里做错了什么? 我需要它与Javascritpt,因为POS通过NodeJS与PC沟通。

哦,顺便说一句, convertStringToArrayBuffer的代码是在这个铬的序列文档:

 var writeSerial=function(str) { chrome.serial.send(connectionId, convertStringToArrayBuffer(str), onSend); } // Convert string to ArrayBuffer var convertStringToArrayBuffer=function(str) { var buf=new ArrayBuffer(str.length); var bufView=new Uint8Array(buf); for (var i=0; i<str.length; i++) { bufView[i]=str.charCodeAt(i); } return buf; } 

编辑testing后,我来到这个algorithm返回一个'z'(小写)与下面的input: \002007C50HOLA\003

 function calculateLRC (str) { var bytes = []; var lrc = 0; for (var i = 0; i < str.length; i++) { bytes.push(str.charCodeAt(i)); } for (var i = 0; i < str.length; i++) { lrc ^= bytes[i]; console.log('lrc: ' + lrc); //console.log('lrcString: ' + String.fromCharCode(lrc)); } console.log('bytes: ' + bytes); return String.fromCharCode(lrc); } 

然而,在尝试读取卡片数据时,如果有一些较长的input和特殊字符 ,LRC有时会变成一个控制字符 ,在我的情况下,我在string中使用它们可能是一个问题。 有没有办法强制LRC避开这些angular色? 或者,也许我做错了,这就是为什么我把这些字符作为输出。

您的基于伪代码的algorithm正在使用加法。 对于XOR版本,试试这个:

 function calculateLRC(str) { var buffer = convertStringToArrayBuffer(str); var lrc = 0; for (var i = 0; i < str.length; i++) { lrc = (lrc ^ buffer[i]) & 0xFF; } return lrc; } 

我认为你在XOR版本上的初始尝试失败了,因为你需要获取字符代码。 numbervariables仍然包含一个string,当你result = result ^ number ,所以结果可能不是你所期望的。

这是一个SWAG,因为我目前没有安装Node.JS,所以我无法validation它会工作。

另一件我会关心的是字符编码。 JavaScript对文本使用UTF-16,所以将任何非ASCII字符转换为8位字节可能会导致意外的结果。

在阅读@Jack A.的答案并将其修改为这个之后,我用下面的方法计算了LRC问题:

 function calculateLRC (str) { var bytes = []; var lrc = 0; for (var i = 0; i < str.length; i++) { bytes.push(str.charCodeAt(i)); } for (var i = 0; i < str.length; i++) { lrc ^= bytes[i]; } return String.fromCharCode(lrc); } 

它做什么的解释:

第一:它将接收到的string转换为ASCII码( charCodeAt() )。

第二:通过在上次计算的LRC(第一次迭代中的0)和每个字符的stringASCII之间执行XOR运算来计算LRC。

第三:它从ASCII转换为它的等价聊天( fromCharCode() ),并将这个字符返回给main函数(或称为它的任何函数)。