我正在使用一个集成销售点(POS)设备的系统,我使用铬系列扫描端口并能够读取信用卡数据。
我面临的问题是,我需要以这种格式从字符串中连接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# 就像这个或这一个,甚至这是用Java写的中找到了一些算法,我甚至在Google的缓存中看到了从这是用Java写的中删除的这个问题,它实际上询问的问题和我一样,但没有任何例子或答案。
我还制作了这个Java算法:
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 (在那里我的知识很差)
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通信与PC通过NodeJS。
哦,顺便说一下,来自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;
}编辑经过测试后,我附带了这个算法,它返回一个'z‘(小写),输入如下:\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);
}然而,由于输入的时间较长,并且在尝试读取卡数据时,LRC有时会变成一个控制字符,在我的示例中,我在字符串中使用它们,这可能是一个问题。有没有办法迫使LRC避免这些字符?或者我做错了,这就是为什么我把这些角色作为输出。
发布于 2015-09-10 16:06:55
在读取@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);
}对其所做工作的解释:
1:--它将接收到的字符串转换为ASCII等效(charCodeAt())。
2:,它通过在最后一次计算的LRC (第一次迭代时为0)和字符串的每个字符的ASCII之间执行一个XOR操作来计算LRC。
3:,它将ASCII转换为等价的chat (fromCharCode()),并将这个字符返回到main函数(或任何称为它的函数)。
发布于 2015-09-08 18:06:05
你的基于伪码的算法正在使用加法。对于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版本的尝试失败了,因为您需要获得字符代码。number变量在执行result = result ^ number时仍然包含一个字符串,因此结果可能与您预期的不一样。
这是一个测试,因为我目前还没有安装Node.JS,所以我无法验证它是否有效。
我会关心的另一件事是字符编码。JavaScript使用UTF-16作为文本,因此将任何非ASCII字符转换为8位字节可能会产生意想不到的结果。
https://stackoverflow.com/questions/32463745
复制相似问题