我正在使用集成了销售点(POS)设备的系统,我使用chrome serial扫描端口并能够读取信用卡数据。
我面临的问题是我需要以这种格式从字符串中连接LRC:
STX
='\ 002'(2 HEX)(文字开头)
LLL
=数据长度(不包括STX或ETX,但命令)。
Command C50
{C =从PC到POS的消息,50在POS上“打印”消息的实际代码}
ETX
='\ 003'(3 HEX)(文字结束)
LRC
= Longitudinal Redundancy Check
消息示例如下:
'\002014C50HELLO WORLD\003'
这里我们可以看到002为STX,014是从C50到D的长度,003是ETX。
我在C#like this one或this one甚至this one in Java中找到了一些算法,我甚至看到this question已从Google的缓存中删除了SO,其实际上也是如此因为我没有例子或答案。
我也制作了这个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();
}
在关注Wikipedia's pseudocode之后,我尝试这样做:
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的代码在chrome序列文档中就是这个:
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有时变成Control Character,在我的情况下,我在我的String上使用它们可能是个问题。有没有办法迫使LRC避开这些角色?或者也许我做错了,这就是我将这些角色作为输出的原因。
答案 0 :(得分:1)
您的基于伪代码的算法正在使用添加。对于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
时仍然包含字符串,因此结果可能与您的预期不符。
这是一个SWAG,因为我目前没有安装Node.JS所以我无法验证它是否可行。
我要关注的另一件事是字符编码。 JavaScript使用UTF-16作为文本,因此将任何非ASCII字符转换为8位字节可能会产生意外结果。