# CRC calculation

• September 27th, 2012, 05:38 AM
thijs
CRC calculation
Hi,

I need to calculate the CRC code from the bytes below, by using the CRC CCiTT Kermit checksum.

This is the complete code of my program: (i am using VB6)

==================================================================================================== ============
Private Sub Command1_Click()

'increase sequence byte value
Label1.Caption = Val(Label1.Caption) + 1

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'begin of CRC calculation
DataCRC1 = Chr\$(bytcommand1) + Chr\$(bytcommand2) + Chr\$(bytcommand3) + Chr\$(bytcommand4) + Chr\$(bytcommand5) + Chr\$(bytcommand6) + Chr\$(bytcommand7)
'Step 1: CRC calculation for every byte of datastring (DataCRC1)
For i = 0 To 255
CRC = i
For J = 1 To 8
If (CRC And 1) = 1 Then
CRC = Fix(CRC / 2) Xor 33800
Else
CRC = Fix(CRC / 2)
End If
Next J
CRCT(i) = CRC
Next i
'Step 2: CRC calculation for all data from datastring (DataCRC1)
CRC = 0
For i = 1 To Len(DataCRC1)
HB1 = Fix(CRC / 256)
LB1 = CRC - (256 * HB1)
CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
Next i
HB1 = Fix(CRC / 256): cc1hb1 = Hex(HB1): If Len(cc1hb1) = 1 Then cc1hb1 = "0" & cc1hb1
LB1 = CRC - (256 * HB1): cc1lb1 = Hex(LB1): If Len(cc1lb1) = 1 Then cc1lb1 = "0" & cc1lb1
'End CRC calculation
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +

On Error GoTo SendError
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.Settings = "19200,n,8,1"
MSComm1.CommPort = 1
Dim bytcommand(9) As Byte
'begin send data
bytcommand(0) = &H16 'SYN startbit
'CRC calculation FROM this part
bytcommand(1) = &H6
bytcommand(2) = &H9
bytcommand(3) = &HA
bytcommand(4) = &HF
bytcommand(5) = &HB
bytcommand(6) = Hex(Label1) 'sequence
bytcommand(7) = &H0
'CRC calculation TILL this part
bytcommand(8) = Hex(HB1) 'crc1
bytcommand(9) = Hex(LB1) 'crc1
'end send data

MSComm1.PortOpen = True
MSComm1.Output = bytcommand
MSComm1.PortOpen = False

Exit Sub

SendError: Exit Sub

End Sub
==================================================================================================== ===========

I am having the following bugs:

Sub or function not defined [CRCT]
and
I am not shure if i get the data for bytcommand 8 and 9 right [the CRC output]

• September 27th, 2012, 11:01 AM
DataMiser
Re: CRC calculation
The error means that you are tryign to call a function that does not exist in the current scope
Code:

CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
If the function exists then it is either on a different form and needs the formname to locate it or it is in a module and not defined as public.

Code:

HB1 = Fix(CRC / 256): cc1hb1 = Hex(HB1): If Len(cc1hb1) = 1 Then cc1hb1 = "0" & cc1hb1
LB1 = CRC - (256 * HB1): cc1lb1 = Hex(LB1): If Len(cc1lb1) = 1 Then cc1lb1 = "0" & cc1lb1

Do not use : to tie multiple lines of code together on the same line. This is very poor programming practice which makes your code harder to read and harder to debug with no upside.

Using : to tie lines together can also have unexpected results in some cases.
• September 27th, 2012, 09:12 PM
firoz.raj
Re: CRC calculation
please always write the code inside the code tags .it is more readable and much better .
Code:

Private Sub Command1_Click()

'increase sequence byte value
Label1.Caption = Val(Label1.Caption) + 1

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'begin of CRC calculation
DataCRC1 = Chr\$(bytcommand1) + Chr\$(bytcommand2) + Chr\$(bytcommand3) + Chr\$(bytcommand4) + Chr\$(bytcommand5) + Chr\$(bytcommand6) + Chr\$(bytcommand7)
'Step 1: CRC calculation for every byte of datastring (DataCRC1)
For i = 0 To 255
CRC = i
For J = 1 To 8
If (CRC And 1) = 1 Then
CRC = Fix(CRC / 2) Xor 33800
Else
CRC = Fix(CRC / 2)
End If
Next J
CRCT(i) = CRC
Next i
'Step 2: CRC calculation for all data from datastring (DataCRC1)
CRC = 0
For i = 1 To Len(DataCRC1)
HB1 = Fix(CRC / 256)
LB1 = CRC - (256 * HB1)
CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
Next i
HB1 = Fix(CRC / 256): cc1hb1 = Hex(HB1): If Len(cc1hb1) = 1 Then cc1hb1 = "0" & cc1hb1
LB1 = CRC - (256 * HB1): cc1lb1 = Hex(LB1): If Len(cc1lb1) = 1 Then cc1lb1 = "0" & cc1lb1
'End CRC calculation
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +

On Error GoTo SendError
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.Settings = "19200,n,8,1"
MSComm1.CommPort = 1
Dim bytcommand(9) As Byte
'begin send data
bytcommand(0) = &H16 'SYN startbit
'CRC calculation FROM this part
bytcommand(1) = &H6
bytcommand(2) = &H9
bytcommand(3) = &HA
bytcommand(4) = &HF
bytcommand(5) = &HB
bytcommand(6) = Hex(Label1) 'sequence
bytcommand(7) = &H0
'CRC calculation TILL this part
bytcommand(8) = Hex(HB1) 'crc1
bytcommand(9) = Hex(LB1) 'crc1
'end send data

MSComm1.PortOpen = True
MSComm1.Output = bytcommand
MSComm1.PortOpen = False

Exit Sub

SendError: Exit Sub

End Sub

• September 27th, 2012, 11:17 PM
dglienna
Re: CRC calculation
Readable means proper SPACING as well...

Also, separate ALL LINES from each other (:) should be CRLF
• September 28th, 2012, 07:38 AM
thijs
Re: CRC calculation
I have made some changes, the program runs well, except the crc output remains 0.

Code:

Private Sub Command1_Click()

'increase sequence byte value
Label1.Caption = Val(Label1.Caption) + 1

On Error GoTo SendError
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.Settings = "19200,n,8,1"
MSComm1.CommPort = 1
Dim bytcommand(9) As Byte
'begin send data

bytcommand(0) = &H16 'SYN startbit

'CRC calculation FROM this part
bytcommand(1) = &H6
bytcommand(2) = &H9
bytcommand(3) = &HA
bytcommand(4) = &HF
bytcommand(5) = &HB
bytcommand(6) = Label1 'sequence
bytcommand(7) = &H0
'CRC calculation TILL this part
'======================
Dim DataCRC1 As String:
Dim DataCRC2 As String:
Dim Tijdelijk As String
Dim CRCT(0 To 255) As Long
Dim CRC As Long
Dim Temp As Long
Dim i As Integer
Dim J As Integer
Dim K As Integer
Dim HB1 As Long
Dim LB1 As Long

'=====================
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'begin of CRC calculation
DataCRC1 = Chr\$(bytcommand1) + Chr\$(bytcommand2) + Chr\$(bytcommand3) + Chr\$(bytcommand4) + Chr\$(bytcommand5) + Chr\$(bytcommand6) + Chr\$(bytcommand7)
'Step 1:  CRC calculation for every byte of datastring (DataCRC1)
For i = 0 To 255
CRC = i
For J = 1 To 8
If (CRC And 1) = 1 Then
CRC = Fix(CRC / 2) Xor 33800
Else
CRC = Fix(CRC / 2)
End If
Next J
''CRCT(i) = CRC
Next i
'Step 2:  CRC calculation for all data from datastring (DataCRC1)
CRC = 0
For i = 1 To Len(DataCRC1)
HB1 = Fix(CRC / 256)
LB1 = CRC - (256 * HB1)
''CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
Next i
HB1 = Fix(CRC / 256):    cc1HB1 = Hex(HB1): If Len(cc1HB1) = 1 Then cc1HB1 = "0" & cc1HB1
LB1 = CRC - (256 * HB1): cc1LB1 = Hex(LB1): If Len(cc1LB1) = 1 Then cc1LB1 = "0" & cc1LB1
'End CRC calculation
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bytcommand(8) = CRC / 256
bytcommand(9) = CRC Mod 256
'end send data

MSComm1.PortOpen = True
MSComm1.Output = bytcommand
MSComm1.PortOpen = False

Text1.Text = CRC / 256
Text2.Text = CRC Mod 256

Label3.Caption = bytcommand(0)
Label4.Caption = "Startbit"
Exit Sub

SendError: Exit Sub

End Sub

• September 28th, 2012, 10:07 AM
DataMiser
Re: CRC calculation
As I pointed out on VBForums all you have done is commented out the function call that was throwing the error
Code:

''CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
of course it doesn't work because apparently this function call is there for a reason. Rather than comment it out you need to add the function to your code. I have no ide what this function actually is supposed to do and have never worked with Kermit CRC calculations. I would think it is one of if not the least used out there.
• September 28th, 2012, 10:10 AM
DataMiser
Re: CRC calculation
Quote:

Originally Posted by firoz.raj
please always write the code inside the code tags .it is more readable and much better

If really doesn't help to repost someones code in code tags unless you also take the time to properly indent each line. without the indents it is no more readable than without the code tags. In fact in some cases it is even less readable as a scroll bar is added and the formatting is unchanged.

The reason for code tags is to preserve formatting for readablity
• September 28th, 2012, 11:47 AM
Eri523
Re: CRC calculation
Quote:

Originally Posted by DataMiser
As I pointed out on VBForums all you have done is commented out the function call that was throwing the error
Code:

''CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
of course it doesn't work because apparently this function call is there for a reason. Rather than comment it out you need to add the function to your code. I have no ide what this function actually is supposed to do and have never worked with Kermit CRC calculations. I would think it is one of if not the least used out there.

Admittedly, I didn't inspect the code really closely and I'm not really familiar with the Kermit protocol, but IMO that line actually isn't even supposed to be a function call, rather an access to an array which is to serve as a CRC table. Such contructs are quite common in CRC implementations I have seen.
• September 28th, 2012, 01:01 PM
DataMiser
Re: CRC calculation
I had not considered that it could refer to an array. In either case it is not defined in the program so VB sees it as a call to a missing function
• September 28th, 2012, 05:04 PM
thijs
Re: CRC calculation
Hi, i want to thank everyone who came up with usefull comment.

Here's my final code, it works properly now.

Code:

Private Sub Command1_Click()

'increase sequence byte value
Label1.Caption = Val(Label1.Caption) + 1

On Error GoTo SendError
If MSComm1.PortOpen = True Then MSComm1.PortOpen = False
MSComm1.Settings = "19200,n,8,1"
MSComm1.CommPort = 1
Dim bytcommand(9) As Byte
'begin send data

bytcommand(0) = &H16 'SYN startbit

'CRC calculation FROM this part
bytcommand(1) = &H6
bytcommand(2) = &H9
bytcommand(3) = &HA
bytcommand(4) = &HF
bytcommand(5) = &HB
bytcommand(6) = Label1 'sequence
bytcommand(7) = &H0
'CRC calculation TILL this part
'======================
Dim DataCRC1 As String:
Dim DataCRC2 As String:
Dim Tijdelijk As String
Dim CRCT(0 To 255) As Long
Dim CRC As Long
Dim Temp As Long
Dim i As Integer
Dim J As Integer
Dim K As Integer
Dim HB1 As Long
Dim LB1 As Long

'=====================
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'begin of CRC calculation
DataCRC1 = Chr\$(bytcommand(1)) + Chr\$(bytcommand(2)) + Chr\$(bytcommand(3)) + Chr\$(bytcommand(4)) + Chr\$(bytcommand(5)) + Chr\$(bytcommand(6)) + Chr\$(bytcommand(7))
'Step 1:  CRC calculation for every byte of datastring (DataCRC1)
For i = 0 To 255
CRC = i
For J = 1 To 8
If (CRC And 1) = 1 Then
CRC = Fix(CRC / 2) Xor 33800
Else
CRC = Fix(CRC / 2)
End If
Next J
CRCT(i) = CRC
Next i
'Step 2:  CRC calculation for all data from datastring (DataCRC1)
CRC = 0
For i = 1 To Len(DataCRC1)
HB1 = Fix(CRC / 256)
LB1 = CRC - (256 * HB1)
CRC = CRCT(LB1 Xor Asc(Mid\$(DataCRC1, i, 1))) Xor HB1
Next i
HB1 = Fix(CRC / 256):    cc1HB1 = Hex(HB1): If Len(cc1HB1) = 1 Then cc1HB1 = "0" & cc1HB1
LB1 = CRC - (256 * HB1): cc1LB1 = Hex(LB1): If Len(cc1LB1) = 1 Then cc1LB1 = "0" & cc1LB1
'End CRC calculation
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

bytcommand(8) = CRC Mod 256
bytcommand(9) = CRC / 256 - 1
'end send data

MSComm1.PortOpen = True
MSComm1.Output = bytcommand
MSComm1.PortOpen = False

Text1.Text = CRC / 256
Text2.Text = CRC Mod 256
Text3.Text = CRC

Label3.Caption = bytcommand(0)
Label4.Caption = "Startbit"
Exit Sub

SendError: Exit Sub

End Sub