使用 Javascript 的 8 位 XOR 校验和
8-bit XOR checksum using Javascript
我正在尝试模仿一个 windows 应用程序,该应用程序 格式化消息并通过 USB 通过 UART 将其发送到显示该消息的设备。
应用程序计算校验和并将其粘贴在消息之后,否则设备将不接受命令。校验和不是 crc8 校验和,但它是什么?
使用 USB 显示器,我看到了以下测试用例:
ASCII:<L1><PA><IB><MA><WC><OM>Test!
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e5465737421
校验和:6A
ASCII:<L1><PA><IB><MA><WC><OM>Testa!
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e546573746121
校验和:0B
ASCII:<L1><PA><IB><MA><WC><OM>Test some more
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e5465737420736f6d65206d6f7265
校验和:4A
ASCII:<L1><PA><IE><MA><WC><OE>[SPACE]
十六进制:3c4c313e3c50413e3c49453e3c4d413e3c57433e3c4f453e20
校验和:52
This website returns 第一行的正确校验和 (CheckSum8 Xor)。我正在尝试模仿该功能。 (注意:当您发送 ASCII 值时网站会崩溃,因为它包含 <>
个字符。请改用 HEX 值!)
目前,我的代码是这样做的:
let hex = ascii2hex('<L1><PA><IB><MA><WC><OM>Test!') // or one of the other ascii values
let checksum = chk8xor(hex)
console.log(checksum)
function ascii2hex(str) {
var arr = [];
for (var i = 0, l = str.length; i < l; i ++) {
var hex = Number(str.charCodeAt(i)).toString(16);
arr.push(hex);
}
return arr;
}
function chk8xor(byteArray) {
let checksum = 0x00
for(let i = 0; i < byteArray.length - 1; i++)
checksum ^= byteArray[i]
return checksum
}
(javascript)
代码有效,但 returns 校验和不正确。例如,第一个测试用例 returns 50
而不是 6A
.
我确定我遗漏了一些简单的东西。
我在做什么与上面提到的网站不同?
这里不需要任何 "hex" 字符串,只需取 ASCII 值并将其与校验和进行异或:
test = [
'<L1><PA><IB><MA><WC><OM>Test!',
'<L1><PA><IB><MA><WC><OM>Testa!',
'<L1><PA><IB><MA><WC><OM>Test some more',
'<L1><PA><IE><MA><WC><OE> ',
]
for (let str of test) {
let cs = 0;
for (let char of str)
cs ^= char.charCodeAt(0)
console.log(str, cs.toString(16))
}
如果喜欢"functional"的风格,可以把内循环写成
let cs = [...str].map(a => a.charCodeAt(0)).reduce((a, b) => a ^ b);
我正在尝试模仿一个 windows 应用程序,该应用程序 格式化消息并通过 USB 通过 UART 将其发送到显示该消息的设备。
应用程序计算校验和并将其粘贴在消息之后,否则设备将不接受命令。校验和不是 crc8 校验和,但它是什么?
使用 USB 显示器,我看到了以下测试用例:
ASCII:<L1><PA><IB><MA><WC><OM>Test!
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e5465737421
校验和:6A
ASCII:<L1><PA><IB><MA><WC><OM>Testa!
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e546573746121
校验和:0B
ASCII:<L1><PA><IB><MA><WC><OM>Test some more
十六进制:3c4c313e3c50413e3c49423e3c4d413e3c57433e3c4f4d3e5465737420736f6d65206d6f7265
校验和:4A
ASCII:<L1><PA><IE><MA><WC><OE>[SPACE]
十六进制:3c4c313e3c50413e3c49453e3c4d413e3c57433e3c4f453e20
校验和:52
This website returns 第一行的正确校验和 (CheckSum8 Xor)。我正在尝试模仿该功能。 (注意:当您发送 ASCII 值时网站会崩溃,因为它包含 <>
个字符。请改用 HEX 值!)
目前,我的代码是这样做的:
let hex = ascii2hex('<L1><PA><IB><MA><WC><OM>Test!') // or one of the other ascii values
let checksum = chk8xor(hex)
console.log(checksum)
function ascii2hex(str) {
var arr = [];
for (var i = 0, l = str.length; i < l; i ++) {
var hex = Number(str.charCodeAt(i)).toString(16);
arr.push(hex);
}
return arr;
}
function chk8xor(byteArray) {
let checksum = 0x00
for(let i = 0; i < byteArray.length - 1; i++)
checksum ^= byteArray[i]
return checksum
}
(javascript)
代码有效,但 returns 校验和不正确。例如,第一个测试用例 returns 50
而不是 6A
.
我确定我遗漏了一些简单的东西。
我在做什么与上面提到的网站不同?
这里不需要任何 "hex" 字符串,只需取 ASCII 值并将其与校验和进行异或:
test = [
'<L1><PA><IB><MA><WC><OM>Test!',
'<L1><PA><IB><MA><WC><OM>Testa!',
'<L1><PA><IB><MA><WC><OM>Test some more',
'<L1><PA><IE><MA><WC><OE> ',
]
for (let str of test) {
let cs = 0;
for (let char of str)
cs ^= char.charCodeAt(0)
console.log(str, cs.toString(16))
}
如果喜欢"functional"的风格,可以把内循环写成
let cs = [...str].map(a => a.charCodeAt(0)).reduce((a, b) => a ^ b);