# HJ212-2017《污染物在线监控（监测）系统数据传输标准》中 CRC 数据校验算法 VB / JS 源码

34 篇文章 1 订阅
32 篇文章 2 订阅
20 篇文章 1 订阅

PS：源代码采集自： HJT212 的CRC循环冗余校验 - 开发者知识库

这几天准备自己写个支持 HJ212-2017《污染物在线监控（监测）系统数据传输标准》的简易数据接收端玩玩，仔细研读通讯协议文本发现通讯中需要对数据块做 CRC16 校验，于是翻出老早些年前的 CRC16 代码，用例子测试了一把（ 标准中19、20页 ），

Public Function crc16Str(s As String) As String
Dim data() As Byte
Dim ReturnData(1) As Byte
Dim CRC_Reg_Lo, CRC_Reg_Hi As Byte
Dim CL, CH As Byte
Dim SaveHi, SaveLo As Byte
Dim i, j As Integer
CRC_Reg_Lo = &HFF
CRC_Reg_Hi = &HFF   'CRC寄存器&H FF FF
CH = &HA0
CL = &H1        '多项式&H A0 01
data = StrConv(s, vbFromUnicode)
For i = 0 To UBound(data)
CRC_Reg_Lo = CRC_Reg_Lo Xor data(i) '依次和寄存器低8位进行异或运算
For j = 0 To 7
SaveHi = CRC_Reg_Hi             '保存高位,是为了判断右移时是否向低位字节进1
SaveLo = CRC_Reg_Lo             '保存地位,是为了判断LSB是否为0
'以下是右移'''''''''''''''''''''''''''''''''''''
CRC_Reg_Hi = CRC_Reg_Hi \ 2
CRC_Reg_Lo = CRC_Reg_Lo \ 2
If ((SaveHi And &H1) = &H1) Then
CRC_Reg_Lo = CRC_Reg_Lo Or &H80
End If
'右移完成'''''''''''''''''''''''''''''''''''''''
If ((SaveLo And &H1) = &H1) Then
CRC_Reg_Hi = CRC_Reg_Hi Xor CH
CRC_Reg_Lo = CRC_Reg_Lo Xor CL
End If
Next j
Next i
ReturnData(0) = CRC_Reg_Lo  '低位
ReturnData(1) = CRC_Reg_Hi  '高位
s = ""
For i = 0 To UBound(ReturnData)
s = Right("00" & Hex(ReturnData(i)), 2) & s
Next
crc16Str = s
End Function

QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&

<html>
<head>
</head>
<body>
<script type="text/javascript">
function strToUtf8Bytes(str) {
const utf8 = [];
for (let ii = 0; ii < str.length; ii++) {
let charCode = str.charCodeAt(ii);
if (charCode < 0x80) utf8.push(charCode);
else if (charCode < 0x800) {
utf8.push(0xc0 | (charCode >> 6), 0x80 | (charCode & 0x3f));
} else if (charCode < 0xd800 || charCode >= 0xe000) {
utf8.push(0xe0 | (charCode >> 12), 0x80 | ((charCode >> 6) & 0x3f), 0x80 | (charCode & 0x3f));
} else {
ii++;
// Surrogate pair:
// UTF-16 encodes 0x10000-0x10FFFF by subtracting 0x10000 and
// splitting the 20 bits of 0x0-0xFFFFF into two halves
charCode = 0x10000 + (((charCode & 0x3ff) << 10) | (str.charCodeAt(ii) & 0x3ff));
utf8.push(
0xf0 | (charCode >> 18),
0x80 | ((charCode >> 12) & 0x3f),
0x80 | ((charCode >> 6) & 0x3f),
0x80 | (charCode & 0x3f),
);
}
}
//兼容汉字，ASCII码表最大的值为127，大于127的值为特殊字符
for(let jj=0;jj<utf8.length;jj++){
var code = utf8[jj];
if(code>127){
utf8[jj] = code - 256;
}
}
return utf8;
}

function getCRC(data212) {
let CRC =0xFFFF;
let num =0xA001;
let inum = 0;
let sb =strToUtf8Bytes(data212);//.getBytes();
for(let j = 0; j < sb.length; j ++) {
inum = sb[j];
CRC = (CRC >> 8) & 0x00FF;
CRC ^= inum;
for(let k = 0; k < 8; k++) {
let flag = CRC % 2;
CRC = CRC >> 1;
if(flag == 1) {
CRC = CRC ^ num;
}
}
}
//console.log(CRC); 7296
return CRC.toString(16).toUpperCase(); //最后别忘了，需要的是16进制结果，Integer.toHexString()
}
console.log(getCRC('QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&'));
document.write(getCRC('QN=20160801085857223;ST=32;CN=1062;PW=100000;MN=010000A8900016F000169DC0;Flag=5;CP=&&RtdInterval=30&&')+'<br/>');

</script>
</body>
</html>

Function CRC16forHJ212_2017(s As String) As String  '(data() As Byte) As Long
Dim r As Long
Dim hi As Byte
Dim flag As Byte
Dim i As Long, j As Long, data() As Byte
data = StrConv(s, vbFromUnicode)
r = &HFFFF&
For j = 0 To UBound(data)
hi = r \ &H100&
hi = hi Xor data(j)
r = hi
For i = 1 To 8
flag = r And 1
r = r \ 2
If flag = 1 Then
r = r Xor &HA001&
End If
Next
Next
CRC16forHJ212_2017 = Right("0000" & Hex(r), 4)
End Function

’------------------

• 0
点赞
• 1
收藏
觉得还不错? 一键收藏
• 打赏
• 0
评论
04-12 3550
04-06 9737
06-01 1400
02-19 485
08-06 7926

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

jessezappy

¥1 ¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。