组态王编写CRC16验证码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//取出 CRC16 码的四个位转换成二进制并连接起来 while(i<5) { ref_B=strmid(ref,i,1); ref_BB=ox_b(ref_B); ret_Before=ret_Before+ref_BB; i=i+1; } //移位,取出最低位 ret_After=strmid(ret_Before,1,15); ret_1=strmid(ret_Before,16,1); ret_After="0"+ret_After; //四个二进制转成一个十六进制,并连接起来 while(j<15) { ret_BB=strmid(ret_After,j,4); ret_B=b_ox(ret_BB); ret_2=ret_2+ret_B; j=j+4; }
自定义脚本名字:b_ox(string ref) 该自定义函数内容: string ret; if(ref=="0000") ret="0"; if(ref=="0001") ret="1"; if(ref=="0010") ret="2"; if(ref=="0011") ret="3"; if(ref=="0100") ret="4"; if(ref=="0101") ret="5"; if(ref=="0110") ret="6"; if(ref=="0111") ret="7";
自定义脚本名字:d_ox(long ref) 该自定义函数内容: string ret="";
if(ref==0) ret="0"; if(ref==1) ret="1"; if(ref==2)
ret="2"; if(ref==3) ret="3"; if(ref==4) ret="4"; if(ref==5) ret="5"; if(ref==6) ret="6"; if(ref==7) ret="7"; if(ref==8) ret="8"; if(ref==9) ret="9"; if(ref==10) ret="A"; if(ref==11) ret="B"; if(ref==12) ret="C"; if(ref==13) ret="D"; if(ref==14) ret="E"; if(ref==15) ret="F"; return ret; 自定义脚本名字:ox_b(string ref) 该自定义函数内容: string ret="";
Network 7
NEXT
Network 8
LD SM0.0 INCD LD6
//指针加 1 指向下一个字节
Network 9
NEXT
Network 10
LD SM0.0 SWAP AC0 MOVW AC0, *LD6
//交换 CRC 寄存器高低字节 //CRC 校验值写入数据区结尾
组态王代码思路
1、异或(xor):将 CRC16 码(转换成二进制是十六位)的低 8 位(八个位)和 数据的 8bit 进行异或,以四个位为单位,转换成十进制,用十进制的异或指令
if(ref=="0") ret="0000"; if(ref=="1") ret="0001"; if(ref=="2") ret="0010"; if(ref=="3") ret="0011"; if(ref=="4") ret="0100"; if(ref=="5") ret="0101";
if(ref=="6") ret="0110"; if(ref=="7") ret="0111"; if(ref=="8") ret="1000"; if(ref=="9") ret="1001"; if(ref=="A") ret="1010"; if(ref=="B") ret="1011"; if(ref=="C") ret="1100"; if(ref=="D") ret="1101"; if(ref=="E") ret="1110"; if(ref=="F") ret="1111"; return ret;
return ret_2;
自定义脚本名字:crc16(string ref) 该自定义函数内容: string crc16="FFFF"; //string crc16_xor="";//异或后
string crc16_shift_B="";//移位后移出的最低位 string crc16_H=""; string crc16_HR=""; string crc16_L=""; string crc16_LR=""; string ref_8=""; long ref_len=0; string ret=""; long ref_start=1; long i=1;
进行异或(“^”这个异或指令是将十进制的数据转换成二进制的数据,逐位进 行异或)。然后在转换成十六进制数,在连接起来。用到 ox_d(十六进制转十 进制)、d_ox(十进制转十六进制)。 2、移位(shift_right):将 CRC16 码逐位转换成二进制,移位,再连接起来。 用到 ox_b(十六进制转二进制)。
之前见过一些将原理的,都没耐心看,下面的这个讲解的很简单。
供大家参考。
网上说明:
整理一个 CRC 校验计算的子程序
TITLE=子程序注释
//
CRC-16 码由两个字节构成,在开始时 CRC 寄存器的每一位都预置
为 1,然后把 CRC 寄存器与 8-bit 的数据进行异或,之后对 CRC 寄存器从高到
SM0.0 AC1, +1, +8
//移位处理循环,处理一个字节的 8
Network 5
LD SM0.0 SRW AC0, 1
//CRC 寄存器右移一位
Network 6 LD SM1.1 XORW 16#A001, AC0 项式 16#A001 异或
//如果移出位为 0,则进入下一次循环 //如果移出位为 1,CRC 寄存器与多
自定义脚本名字:ox_d(string ref) 该自定义函数内容: long ret=0;
if(ref=="0")
ret=0; if(ref=="1") ret=1; if(ref=="2") ret=2; if(ref=="3") ret=3; if(ref=="4") ret=4; if(ref=="5") ret=5; if(ref=="6") ret=6; if(ref=="7") ret=7; if(ref=="8") ret=8; if(ref=="9") ret=9; if(ref=="A") ret=10; if(ref=="B") ret=11; if(ref=="C") ret=12; if(ref=="D") ret=13; if(ref=="E") ret=14; if(ref=="F") ret=15; return ret;
低进行移位,在最高位(MSB)的位置补零,而最低位(LSB),移位后已经被
移出 CRC 寄存器)如果为 1,则把寄存器与预定义的多项式码(16#A001)进
行 异或,否则如果 LSB 为零,则无需进行异或。重复上述的由高至低的移位 8
次,第一个 8-bit 数据处理完毕,用此时 CRC 寄存器的值与下一个 8-bit 数据异
} return ret;
自定义脚本名字:shift_right(string ref) 该自定义函数内容:
//对 CRC16 码进行移位,返回移位结果 string ref_B=""; string ref_BB="";//转化成二进制 string ret_Before="";//移位之前的二进制串 string ret_After="";//移位之后的二进制串 string ret_1="";//移出的最低位 string ret_2="";//移位后的十六进制数 string ret_B=""; string ret_BB=""; long i=1; long j=1;
if(ref=="1000") ret="8"; if(ref=="1001") ret="9"; if(ref=="1010") ret="A"; if(ref=="1011") ret="B"; if(ref=="1100") ret="C"; if(ref=="1101") ret="D"; if(ref=="1110") ret="E"; if(ref=="1111") ret="F"; return ret;
{ crc16_shift_B=shift_right_b(crc16); crc16=shift_right(crc16); if(crc16_shift_B=="1")
{ crc16_H=strmid(crc16,1,2); crc16_HR=xor("A0",crc16_H); crc16_L=strmid(crc16,3,2); crc16_LR=xor("01",crc16_L); crc16=crc16_HR+crc16_LR; } i=i+1; } ref_start=ref_start+2; ref_len=ref_len-2; i=1; } return crc16;
// 7.最终 CRC 寄存器的内容即为 CRC 值。
//
// 输入参数: // 待校验数据区指针,第一个字节为数据长度
// LD0
Dat SM0.0 MOVW 16#FFFF, AC0 BTI *LD0, LW4
//初始化 CRC 寄存器 //数据缓冲区第一个字节为数据长度
ref_len=strlen(ref); while(ref_len) { ref_8=strmid(ref,ref_start,2); crc16_L=strmid(crc16,3,2); crc16_LR=xor(ref_8,crc16_L); crc16_H=strmid(crc16,1,2); crc16=crc16_H+crc16_LR; while(i<9)
贴图及代码:
自定义脚本名字:xor(string ref1,string ref2) 该自定义函数内容: string ref1_B=""; string ref2_B=""; long data1_B=0; long data2_B=0; long data_D=0; string data=""; string ret=""; long i=1; long j=0;
MOVD LD0, LD6 INCD LD6
//指针指向第一个待处理字节
Network 2
LD SM0.0 FOR AC2, +1, LW4
//开始循环处理每一个字节
Network 3
LD SM0.0 XORB *LD6, AC0 异或
//字节首先与 CRC 寄存器低位进行
Network 4
LD FOR 位
while(i<3) { ref1_B=StrMid(ref1,i, 1); ref2_B=strmid(ref2,i,1); data1_B=ox_d(ref1_B); data2_B=ox_d(ref2_B); data_D=data1_B^data2_B; data=d_ox(data_D); ret=ret+data; i=i+1;
或并进行如前一个数据似的 8 次移位。所有的字符处理完成后 CRC 寄存器内的
值即为最终的 CRC 值。
// 下面为 CRC 的计算过程:
// 1.设置 CRC 寄存器,并给其赋值 FFFF(hex)。
// 2.将数据的第一个 8-bit 字符与 16 位 CRC 寄存器的低 8 位进行异或,并
把结果存入 CRC 寄存器。
// 3.CRC 寄存器向右移一位,MSB 补零,移出并检查 LSB。
// 4.如果 LSB 为 0,重复第三步;若 LSB 为 1,CRC 寄存器与多项式码相
异或。
// 5.重复第 3 与第 4 步直到 8 次移位全部完成。此时一个 8-bit 数据处理完
毕。
// 6.重复第 2 至第 5 步直到所有数据全部处理完成。
批注本地保存成功开通会员云端永久保存去开通
最近进行 CRC16 验证码的计算,由于组态王语言的局限性,不能 使用网络上的 C 代码,于是自己琢磨进行编写。思路是网上的朋 友写下来的,很感谢网上的朋友们的无私贡献。鉴于组态王写这 一部分的资料很少很难找(我没找到)。我将我写的代码共享出 来。技术有限,用到的很多方法都很笨拙,大家请勿笑话,也欢 迎提出改进方案。本文档还是写给懒得去看 CRC 的原理的同行 们,不妨就用这些代码试试吧!
相关文档
最新文档