2014-10-30 211 views
3

很遗憾,我不得不承认,我放弃了在VBA编程语言中8小时搜索正确的CRC8代码。 有很多例子,但我还没有找到适合我的例子。所以在这里,请求你的帮助,如果有人可以给我写这段代码,或者如果有一个神秘的链接,我没有点击。在VBA中计算CRC8

说明:

AppID = "A00000039656434103F0154020D4000A" 

在我的项目,则要求字符“A”在这的AppID结束,因为在此基础上的CRC8应计算。如果理解正确的我有32-byte ID,关于这一点我想要做的16bits的CRC8检查(因为我可能在试图写这个CRC8功能整天都疯了)(这是否有道理?)

在给定的例子,我的CRC8应该返回什么只有结果:

CRC8 = 0x6D 

,我需要更换下部nible与字符“A”在我的主要的AppID:

FinalAppID = "A00000039656434103F0154020D4000D" 

问题:但我根本不知道如何编写,也无法将C++/C#中的代码进行转换。而且我一步一步地完成转换,但它没有奏效。

这是我使用的代码:

​​

我现在不在办公室,所以有可能在上面的代码中错别字,或者一些愚蠢的错误,我刚才写的我的头,因为我一整天都在用它。

与上述代码发生的问题是:

错误:

Error: Overflow! 

即使我通过entire string,或只是16bits发生该错误。同样的错误。

如果有人有什么可以帮助我的话,我会非常感激他!

+0

你知道哪一行会导致溢出吗?你确定你的UDF工作正常吗? – James 2014-10-30 22:20:53

+0

不幸的是@James我不是那么好的VBA,最近刚刚开始编码,只是因为他们告诉我的这个“小”项目。我不是很好,但在调试。但是,当我MsgBox的CRC8 ..我有一些奇怪的数字..如大负数。 我会再次检查StringToArray函数。但我认为它工作正常,我做了一些测试。 我也尝试关闭错误消息,但我找不到这样做的选项?当我搜索如何将其关闭时,我没有在网络上的每个链接中提到的解决方案资源管理器。 – 2014-10-30 22:23:50

+0

这是一个有趣的问题,但您确实需要用*** ***代码替换它,并让我们知道发生错误的位置。 – RubberDuck 2014-10-31 09:52:25

回答

4

这是一个版本的几个修复程序,它可以防止发生溢出。它为您的十六进制字节(A00000039656434103F0154020D4000A)生成预期结果(& H6D)。

Public Function calculateCRC8(ByVal AppID As String) As String 
    Dim CRC8 As Byte 
    Dim i As Integer 
    Dim j As Integer 
    Dim AppIDarray() As Byte '<--- explicitly dimensioned as a Byte array to avoid confusion 


    CRC8 = &HC7 

    'The AppID is actually bytes stored in hexadecimal in a string. You have to convert them back to bytes before you can run a crc8 on them. 
    AppIDarray = HexToByte(AppID) 
    aidLength = UBound(AppIDarray) 
      For j = 0 To aidLength 
       CRC8 = CRC8 Xor AppIDarray(j) 
       For i = 1 To 8 
        If CRC8 And &H80 Then 
        'masking off the left-most bit before shifting prevents the Overflow error. 
        CRC8 = ((&H7F And CRC8) * 2) Xor &H1D 
        Else 
        CRC8 = CRC8 * 2 
        End If 
       Next i 
      Next j 
    calculateCRC8 = CRC8 
End Function 

该函数接受一个十六进制字符串并将其解释为Byte数组。

Public Function HexToByte(strHex As String) As Byte() 
    Dim i As Integer 
    Dim tempByte As Byte 
    Dim outBytes() As Byte 
    ReDim outBytes(Len(strHex) \ 2 - 1) 
    For i = 0 To Len(strHex) \ 2 - 1 
     For j = 0 To 1 
      char = Mid(strHex, i * 2 + j + 1, 1) 
      Select Case char 
       Case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9": 
        tempByte = tempByte Or (Asc(char) - 48) 
       Case "A", "B", "C", "D", "E", "F": 
        tempByte = tempByte Or (Asc(char) - 55) 
      End Select 
      If j = 0 Then 
       tempByte = tempByte * 2^4 
      Else 
       outBytes(i) = tempByte 
       tempByte = 0 
      End If 
     Next 
    Next 
    HexToByte = outBytes 
End Function 
+0

太棒了!恭喜BlackHawk,在第一次测试中,它完全按照它应该的方式运行,并且我得到了CRC8的确切值,就像我在示例Task中的那样!非常感谢你! – 2014-10-31 15:15:29

+1

@AndroidNFC修改代码时,我用[这个在线crc计算器来验证它](http://www.zorc.breitbandkatze.de/crc.html)。对于您的实现,crc顺序为8,crc poly为1D,初始值为C7,最终异或值为0.遗憾的是,该站点不允许以十六进制字节输入数据,因此您只能执行常规字符串,但它仍然提供了一个很好的比较来测试针对的实现。 – Blackhawk 2014-10-31 15:36:10