CRC16 Checksumme berechnen

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Dagobärt.

    CRC16 Checksumme berechnen

    Schönen guten tag
    Ich hab die letzten Tage damit verbracht, mich durch sämtliche Seiten des internets zu forsten und doch bin ich hier gelanden, weil ich nicht weiterkomme.
    Dazu muss ich sagen, dass ich ein Neuling in VB bin und auch nur begrenzte Kenntnisse in C++ und Java habe. Aber irgendwo muss man ja anfangen :D

    Ich möchte eine Funktion erstellen, die aus einem Array von bytes eine checksumme errechnet, die aus 2 bytes besteht.
    Die Bytes liegen in hexadezimalform vor. zB.: 3f 00 ff 04

    Ich habe diesen code probiert:
    tek-tips.com/viewthread.cfm?qid=1587721
    - hier habe ich probleme bei den Zeilen mit Text3.Text = Right("0000" & Hex(CRC), 4)... und Open App.Path...

    und diesen:
    devx.com/vb2themax/Tip/19241
    - dieser code wurde auf vielen seiten, angepriesen, aber rechnet bei mir falsch
    - hier wär es schön, wenn ihn jmd ausprobieren könnte und guckt, ob er funktioniert.

    Danke schon mal im vorraus für eure unterstützung

    VB.NET-Quellcode

    1. '
    2. ' CRC16CCIT.ComputeCheckSum will return ushort with CRC16
    3. ' CRC16CCIT.ComputeCheckSumBytes will return 2 bytes (hi and low)
    4. Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    5. Dim checksumcalculator = New CRC16CCITT(CRC16CCITT.InitialCRCValue.NonZero1)
    6. Dim value() As Byte = System.Text.Encoding.ASCII.GetBytes("123456789")
    7. MsgBox(Format(checksumcalculator.ComputeCheckSum(value), "X2")) ' 29B1
    8. End Sub
    9. Public Class CRC16CCITT
    10. Public Enum InitialCRCValue
    11. Zeroes = 0
    12. NonZero1 = &HFFFF
    13. NonZero2 = &H1D0F
    14. End Enum
    15. Private Const poly As UShort = &H1021
    16. Dim table(255) As UShort
    17. Dim intValue As UShort = 0
    18. Public Function ComputeCheckSum(ByVal bytes As Byte()) As UShort
    19. Dim crc As UShort = Me.intValue
    20. For i As Integer = 0 To bytes.Length - 1
    21. crc = CUShort(((crc << 8) Xor table(((crc >> 8) Xor (&HFF And bytes(i))))))
    22. Next
    23. Return crc
    24. End Function
    25. Public Function ComputeCheckSumBytes(ByVal bytes As Byte()) As Byte()
    26. Dim crc As UShort = ComputeCheckSum(bytes)
    27. Return BitConverter.GetBytes(crc)
    28. End Function
    29. Public Sub New(ByVal initialvalue As InitialCRCValue)
    30. Me.intValue = CUShort(initialvalue)
    31. Dim temp, a As UShort
    32. For i As Integer = 0 To table.Length - 1
    33. temp = 0
    34. a = CUShort(i << 8)
    35. For j As Integer = 0 To 7
    36. If ((temp Xor a) And &H8000) <> 0 Then
    37. temp = CUShort((temp << 1) Xor poly)
    38. Else
    39. temp <<= 1
    40. End If
    41. a <<= 1
    42. Next
    43. table(i) = temp
    44. Next
    45. End Sub
    46. End Class
    wow, das ging ja echt schnell. Vielen vielen dank für die antworten.
    es klappt alles super. leider bin ich auf ein kleines problem gestoßen.

    laut anleitung meines controllers, den ich mit VB ansprechen will, soll aus CA 00 00 00 00 05 7E 04 00 FF 00 00
    die prüfsumme B5 E1 entstehen.

    als erstes habe ich ein sub hinzugefügt:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim barray(11) As Byte
    3. ' CA 00 00 00 00 05 7E 04 00 FF 00 00
    4. barray(0) = &HCA
    5. barray(1) = &H0
    6. barray(2) = &H0
    7. barray(3) = &H0
    8. barray(4) = &H5
    9. barray(5) = &H7E
    10. barray(6) = &H4
    11. barray(7) = &H0
    12. barray(8) = &HFF
    13. barray(9) = &H0
    14. barray(10) = &H0
    15. Dim checksumcalculator = New CRC16CCITT(&HFFFF) 'init value = &HFFFF
    16. MsgBox(Format(checksumcalculator.ComputeCheckSum(barray), "X2"))
    17. End Sub


    ich erhalte leider 5d0f

    weiß zufällig jemand wo mein fehler liegt??


    im manual des controlers wird die checksumme so berechnet (in C)

    Quellcode

    1. static UINT16 usp_crc; // initialise per packet with $FFFF.
    2. void process_crc(UCHAR8 ucData){
    3. int i;
    4. usp_crc^=ucData;
    5. for(i=0;i<8;i++){ // Process each Bit
    6. if(usp_crc&1){ usp_crc >>=1; usp_crc^=0xA001;}
    7. else{ usp_crc >>=1; }
    8. }
    9. }


    Edit by hal2000:
    - ROT ist der Moderation vorbehalten.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „hal2000“ ()

    Nur mal kurz am Rande: Du musst auch beachten das es zwei verschiedene CRC16 Polynome gibt. Das "normale" mit g(p) = p^16 + p^12 + p^2 + 1 und das vom CCITT (ITU) standardisierte g(p) = p^16 + p^12 + p^5 + 1 (worauf sich auch Manawyrms Code vom Namen her bezieht).
    Ausprobiert?


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    g(p) = p^16 + p^12 + p^5 + 1 ---> 10001000000100001 (binär) ---> 11021 (hexadez)
    g(p) = p^16 + p^12 + p^2 + 1 ---> 10001000000000101 (binär) ---> 11005 (hexadez)
    richtig?

    warum ist dann in dem programm &H1021 statt &H11021 angegeben?
    und wenn ich statt &H1021 &H1005 eingebe, kommt DD8C, statt B5 E1 raus.

    irgendjemnd ne idee?
    im anhang befindet sich das projekt

    DANKE

    Edit by hal2000:
    - ROT ist der Moderation vorbehalten.
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „hal2000“ ()

    Hallo Dagobärt,

    das Problem ist der verwendete Algorythmus.
    Dein MCU verwendet CRC-16 Modbus.

    VB.NET-Quellcode

    1. Public Class Crc16
    2. Private Shared CrcTable As UShort() = {&H0, &Hc0c1, &Hc181, &H140, &Hc301, &H3c0, _
    3. &H280, &Hc241, &Hc601, &H6c0, &H780, &Hc741, _
    4. &H500, &Hc5c1, &Hc481, &H440, &Hcc01, &Hcc0, _
    5. &Hd80, &Hcd41, &Hf00, &Hcfc1, &Hce81, &He40, _
    6. &Ha00, &Hcac1, &Hcb81, &Hb40, &Hc901, &H9c0, _
    7. &H880, &Hc841, &Hd801, &H18c0, &H1980, &Hd941, _
    8. &H1b00, &Hdbc1, &Hda81, &H1a40, &H1e00, &Hdec1, _
    9. &Hdf81, &H1f40, &Hdd01, &H1dc0, &H1c80, &Hdc41, _
    10. &H1400, &Hd4c1, &Hd581, &H1540, &Hd701, &H17c0, _
    11. &H1680, &Hd641, &Hd201, &H12c0, &H1380, &Hd341, _
    12. &H1100, &Hd1c1, &Hd081, &H1040, &Hf001, &H30c0, _
    13. &H3180, &Hf141, &H3300, &Hf3c1, &Hf281, &H3240, _
    14. &H3600, &Hf6c1, &Hf781, &H3740, &Hf501, &H35c0, _
    15. &H3480, &Hf441, &H3c00, &Hfcc1, &Hfd81, &H3d40, _
    16. &Hff01, &H3fc0, &H3e80, &Hfe41, &Hfa01, &H3ac0, _
    17. &H3b80, &Hfb41, &H3900, &Hf9c1, &Hf881, &H3840, _
    18. &H2800, &He8c1, &He981, &H2940, &Heb01, &H2bc0, _
    19. &H2a80, &Hea41, &Hee01, &H2ec0, &H2f80, &Hef41, _
    20. &H2d00, &Hedc1, &Hec81, &H2c40, &He401, &H24c0, _
    21. &H2580, &He541, &H2700, &He7c1, &He681, &H2640, _
    22. &H2200, &He2c1, &He381, &H2340, &He101, &H21c0, _
    23. &H2080, &He041, &Ha001, &H60c0, &H6180, &Ha141, _
    24. &H6300, &Ha3c1, &Ha281, &H6240, &H6600, &Ha6c1, _
    25. &Ha781, &H6740, &Ha501, &H65c0, &H6480, &Ha441, _
    26. &H6c00, &Hacc1, &Had81, &H6d40, &Haf01, &H6fc0, _
    27. &H6e80, &Hae41, &Haa01, &H6ac0, &H6b80, &Hab41, _
    28. &H6900, &Ha9c1, &Ha881, &H6840, &H7800, &Hb8c1, _
    29. &Hb981, &H7940, &Hbb01, &H7bc0, &H7a80, &Hba41, _
    30. &Hbe01, &H7ec0, &H7f80, &Hbf41, &H7d00, &Hbdc1, _
    31. &Hbc81, &H7c40, &Hb401, &H74c0, &H7580, &Hb541, _
    32. &H7700, &Hb7c1, &Hb681, &H7640, &H7200, &Hb2c1, _
    33. &Hb381, &H7340, &Hb101, &H71c0, &H7080, &Hb041, _
    34. &H5000, &H90c1, &H9181, &H5140, &H9301, &H53c0, _
    35. &H5280, &H9241, &H9601, &H56c0, &H5780, &H9741, _
    36. &H5500, &H95c1, &H9481, &H5440, &H9c01, &H5cc0, _
    37. &H5d80, &H9d41, &H5f00, &H9fc1, &H9e81, &H5e40, _
    38. &H5a00, &H9ac1, &H9b81, &H5b40, &H9901, &H59c0, _
    39. &H5880, &H9841, &H8801, &H48c0, &H4980, &H8941, _
    40. &H4b00, &H8bc1, &H8a81, &H4a40, &H4e00, &H8ec1, _
    41. &H8f81, &H4f40, &H8d01, &H4dc0, &H4c80, &H8c41, _
    42. &H4400, &H84c1, &H8581, &H4540, &H8701, &H47c0, _
    43. &H4680, &H8641, &H8201, &H42c0, &H4380, &H8341, _
    44. &H4100, &H81c1, &H8081, &H4040}
    45. Public Shared Function ComputeCrc(data As Byte()) As UInt16
    46. Dim crc As UShort = &Hffff
    47. For Each datum As Byte In data
    48. crc = CUShort((crc >> 8) Xor CrcTable((crc Xor datum) And &Hff))
    49. Next
    50. Return crc
    51. End Function
    52. End Class


    Dürfte dein Problem ganz gut lösen ;)

    Gruß,
    Manawyrm

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Manawyrm“ ()