求教vb串口通信纠错计算方法问题

hisungao 2013-01-06 09:19:18
抓到通信的包,多的时候有100多个数据,倒数第二和第三个字节能根据内容发生变化,用书上说的最简单方法好象不是除255这种方式,学生愚笨没学CRC和其它校检算法,求教大师们能解答采用的纠错计算方法吗?能指导怎么计算吗?下面的是最短的三组数据:
aa c1 2a 45 42 bb ------第一组
aa c7 2a 45 44 bb ------第二组
aa d1 30 32 30 30 30 31 2a 46 38 bb ------第三组
高分感谢!
...全文
1099 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
嗷嗷叫的老马 2013-01-14
  • 打赏
  • 举报
回复
因为平时我也主要搞工控编程,所以效验是比较常见的.但一般是CRC16以及和效验比较多,你这种XOR再加一个变化的倒是头一次见.
hisungao 2013-01-08
  • 打赏
  • 举报
回复
myjian师傅,能讲解一下思路吗?我好象还是没懂,不好意思边学边看的弟子比较笨.
hisungao 2013-01-08
  • 打赏
  • 举报
回复
谢谢两位指点!
of123 2013-01-08
  • 打赏
  • 举报
回复
就是 1 跳过 AA,从第二个字节起,逐字节异或,得到一个字节的异或结果。 2 把异或结果拆成两个字节,方法是,将半字节的值 0 - 9, A - F 当作字符取 ASCII 码,得到 &H30 - &H39, &H41 - &H46。即 0 - 9 加上 &H30,A - F 加上 &H37。

Private Sub Command1_Click()

Dim data As String, i As Long, byteXor As Byte, chr() As String, C1 As Byte, C2 As Byte

data = "AA C6 30 30 32 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 43 BB"
'data = "AA C6 30 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 45 BB"
'data = "AA C6 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 31 33 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 44 BB"

chr() = Split(data, " ")

For i = 1 To UBound(chr) - 3
    byteXor = byteXor Xor Val("&H" & chr(i))
Next i

C1 = byteXor \ 16
C2 = byteXor And &HF


If C1 < 10 Then         '0 - 9
    C1 = C1 + &H30
Else                    'A - F (10 - 15)
    C1 = C1 + &H37
End If

If C2 < 10 Then
    C2 = C2 + &H30
Else
    C2 = C2 + &H37
End If

Debug.Print Hex(C1), Hex(C2)
End Sub
worldy 2013-01-07
  • 打赏
  • 举报
回复
引用 9 楼 hisungao 的回复:
现在感觉它不象是用了CRC这样的计算方法,我调动参数发送到单片机后检测到的尾数中2a 45 XX bb会变化,现在基本上知道2a之前发除了开头第一第二字节外全都是数据,按说用了CRC这样的计算那么校检数XX重合的可能比较小,但用一个一个数据调动重合的机率比较大,单独调前一个参数或后一个参数就有很多都是重合了,从数据量最少的来说: aa c1 2a 45 42 bb -------……
有一种校验是对字节数值直接相加,然后抛弃高位 单片机的校验就是这样
of123 2013-01-07
  • 打赏
  • 举报
回复
从校验码变化规律看,不会是 CRC 算法。前两组数据虽然只差 2 个比特,但 CRC 校验码应该面目全非,不会像它这样只差 1 个比特。 这样的纠错算法,碰撞率应该是比较高的。
嗷嗷叫的老马 2013-01-07
  • 打赏
  • 举报
回复
还好这个表不是随机表,是顺序表,不然就得不断接收数据,把所有表中的内容都拿到手后才可以反表出来.
嗷嗷叫的老马 2013-01-07
  • 打赏
  • 举报
回复
嘿,运气真是好,居然一次就猜中 果然是有一张表,与我上面的猜测一样,刚写了个代码一验证,完全正确啊哈哈.
Private Sub Command1_Click()
    Dim I As Long, J As Byte, K As String, L() As String
    
    K = "AA C6 30 30 32 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 43 BB"
    'K = "AA C6 30 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 45 BB"
    'K = "AA C6 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 31 33 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 44 BB"
    
    L() = Split(K, " ")
    J = CByte("&H" & L(1)) Xor CByte("&H" & L(2))
    For I = 3 To UBound(L) - 3
        J = J Xor CByte("&H" & L(I))
    Next
    
    K = Hex(J)
    I = Asc(Mid(K, 1, 1))
    J = Asc(Mid(K, 2, 1))
    
    Select Case I
        Case Is < 58            '数字
            I = I - 18
        Case Is > 64            '字母
            I = I - 24
    End Select
    
    Select Case J
        Case Is < 58            '数字
            J = J - 18
        Case Is > 64            '字母
            J = J - 24
    End Select
    
    Debug.Print I, J
End Sub
这次纯粹是运气好,哈哈. 下次你还是得去找厂家,至少你的运气没我好,我可是一次猜中,等下我是不是考虑去买个彩票哇哈哈
嗷嗷叫的老马 2013-01-07
  • 打赏
  • 举报
回复
这个最好还是向生产厂家寻求帮助. 自己反推出这个算法的话可能会比较麻烦,而且仅能使用人肉穷举法-------把自己能想到的各种算法都用来对这些数据进行计算,想想工作量吧. 而我对这个效验算法的看法与of123相同,这应该不是CRC之类的摘要算法,有可能是类似累加和效验或者XOR的算法,就是把所有数据加起来再取最低两位,然后再在这个结果上进行一次查表,得到最终结果. aa c1 2a 45 42 bb ------第一组 aa c7 2a 45 44 bb ------第二组 aa d1 30 32 30 30 30 31 2a 46 38 bb ------第三组 从这个数据上来看: C1 XOR 2A = EB,效验是45 42 C7 XOR 2A = ED,效验是45 44 d1 30 32 30 30 30 31 2a 一路XOR过来是F8,而效验是46 38. 因此我猜测有一张表,其中45=E,而46=F,则有可能这张表是以31=1到40=0代表数字,41=A开始直到67=Z. 不过后面的长数据好象又不是这么回事.....如果真是有个表的话,那你得收到足够的数据,把这个表先穷举出来再说. 反正头大,最好还是找厂家吧,开发这些设备肯定是要找厂家的.
hisungao 2013-01-07
  • 打赏
  • 举报
回复
现在感觉它不象是用了CRC这样的计算方法,我调动参数发送到单片机后检测到的尾数中2a 45 XX bb会变化,现在基本上知道2a之前发除了开头第一第二字节外全都是数据,按说用了CRC这样的计算那么校检数XX重合的可能比较小,但用一个一个数据调动重合的机率比较大,单独调前一个参数或后一个参数就有很多都是重合了,从数据量最少的来说: aa c1 2a 45 42 bb ----------------第一组 aa c7 2a 45 44 bb ------------------第二组 仅两组中的2a 45 XX bb 就和尝试多次发一百多个数据包的校检结尾很多都相同,加来加去还没搞清楚这家伙用的是什么计算方法。从自己目前所得到的数据来看,唯一怀疑的就只有那个XX了,难道说他们真是定义的加多少减多少这种不怕麻烦的方式啊?下面三组是我调动参数后检测到的数据: 2.1 AA C6 30 30 32 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 43 BB 10.0 AA C6 30 31 30 30 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 45 BB 1.3 AA C6 30 30 30 31 30 30 30 30 30 30 30 31 30 30 30 30 30 30 31 33 30 30 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 32 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 2A 45 44 BB 感觉跟字节有很大关系,不管是哪个只要是字节内容相同,那么2A 45 XX BB就就会相同,求问都有哪些跟字节相关的校检方式?非常感谢了!
worldy 2013-01-06
  • 打赏
  • 举报
回复
注意:BufLen 是参与计算的数据的长度
worldy 2013-01-06
  • 打赏
  • 举报
回复
这是一个完整的crc算法,可以直接使用 http://blog.csdn.net/worldy/article/details/7424659 输入:字节经计算后,填入数据的后面 输出:含crc数据的数组经函数计算后,必须为0
hisungao 2013-01-06
  • 打赏
  • 举报
回复
你上面说的我大概懂,但自己不懂CRC,从 aa c1 2a 45 42 bb ------第一组 aa c7 2a 45 44 bb ------第二组 来看唯一变化的只有c1和c7,但后面变化的是42和44应该不是用的(STX+ADD+CMD+[Data])/255=CHECK这方法,多的时候有118个数据,看来自己是不会算了. :(
贝隆 2013-01-06
  • 打赏
  • 举报
回复
通常情况下 通信的命令桢格式如下: STX+ADD+CMD+[Data]+ETX+CHECK STX:通信命令起始符号,是一个通信命令桢的开始。这个字符不可重复。 ADD:下位机地址,每个下位机都拥有惟一的下位机地址,它标识了上位机通信的对象,不可重复。有些通信是上位机和下位机1:1通信,那就没有下位机地址,此项可去除。 CMD:通信命令,用户定义通信功能,一般分为:读写两种。 Data:可选,作为对CMD的补充,比如你要对下位机写数据,那么这个Data就可以作为写入的数据。 ETX:通信命令桢的结束符号,是一个命令桢的结束,这个字符也是不可重复的。 CHECK:校验和,一般是对从STX到ETX的一种校验计算,通信双方可以通过算法计算出正确的校验值,和这个通信接收到的值进行比较,如果相同,表示本次通信正确,如果不相同表示本次通信不正确。 就你的情况而言,CRC校验,是有标准定义的,参阅:http://wenku.baidu.com/view/2d2dc14cf7ec4afe04a1dfef.html
hisungao 2013-01-06
  • 打赏
  • 举报
回复
我日日日,不知道这个变态的用什么来校检的.我也是试了搞不清楚规律来.
of123 2013-01-06
  • 打赏
  • 举报
回复
至少算出的值与最常用的十几种 CRC-16 协议不符。
hisungao 2013-01-06
  • 打赏
  • 举报
回复
我也搜到一个CRC校检的小程序,算CRC16和CRC32的,请问大侠们估计这个是用的CRC16的吗?

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧