We help IT Professionals succeed at work.

Help required to convert a C++ Code to Ms Access VBA

Is it possible to get assistance on converting the CRC  Code below which was done in C++ to MS Access VBA


unsigned short int cal_crc(unsigned char *ptr, unsigned int len)
{
unsigned char i;
unsigned int crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if((crc&0x8000)!=0)
{
crc*=2;
crc^=0x18005;
}
else
{
crc*=2;
}
if((*ptr&i)!=0)
crc^=0x18005;
}
ptr++;
}
return(crc);

Open in new window

Comment
Watch Question

Bill PrewTest your restores, not your backups...
Expert of the Year 2019
Top Expert 2016

Commented:
Can you provide some test data and the desired CRC results to be calculated from that input?


»bp
Scott McDaniel (EE MVE )Infotrakker Software
Most Valuable Expert 2012
Top Expert 2014

Commented:

If your goal is to calculate the CRC for a given string or file, perhaps this would work:


http://www.freevbcode.com/ShowCode.asp?ID=655


Also, FMS Total Visual Sourcebook has functions that do this. TVS is a purchased product, but it has a LOT of code and can save you tons of time:


https://www.fmsinc.com/MicrosoftAccess/modules/index.asp

Dear Bill Prew;

Kindly see below the information provided from the INSPUR ESD Device below:

The contents of the interface protocol include three commands (request/response), such as Get Status, Invoice signing and error message. All the data will be organized in JSON format starting with package header and ending with checksum. It consists of Header, Command ID, Length of data, Content and Verification Code (CRC):

Detailed description of the device:

Field
Header1    = 1 Length Byte (The first byte of package header 0x1A
Header2    = 1 Length Byte (The first byte of package header 0x5D
CmdID       = 1 Command IDs : (0x01 acquire the status of the device, 0x02 invoice signing, 0x03 Error code)
Length       = 4  The length of the content, big-endian
Content  = ? Data to be sent
CRC = 2 (Two-Byte verification (CRC), it will be generated by bytes start from Header to Content)

Regards
Bill PrewTest your restores, not your backups...
Expert of the Year 2019
Top Expert 2016

Commented:
Kindly see below the information provided from the INSPUR ESD Device below:

That didn't answer my question, I am looking for some test data to know if the converted VBA routine is working properly, that is what I wanted you to provide.

For example "0123456789" seems  to generate a crc value of 64788, is that correct, and what you seek?


»bp
Yes Bill Prew that is very correct I have asked the provider of the gadget.

Regards

Chris
Dear Bill Prew;

Kindly note that the CRC will be changing according to the information sent as per given parameters below:


 Field

Header1    = 1 Length Byte (The first byte of package header 0x1A
Header2    = 1 Length Byte (The first byte of package header 0x5D
CmdID       = 1 Command IDs : (0x01 acquire the status of the device, 0x02 invoice signing, 0x03 Error code)
Length       = 4  The length of the content, big-endian
Content  = ? Data to be sent
CRC = 2 (Two-Byte verification (CRC), it will be generated by bytes start from Header to Content)


For example the Content  = ? Data to be sent  

May have a length of 864 bytes or more depending to the invoice lines created or even less


Sorry for that.

Regards

Chris
Dear Bill Prew;

Any lucky there!

Regards

Chris
Bill PrewTest your restores, not your backups...
Expert of the Year 2019
Top Expert 2016

Commented:
This will take time to work up, there are several critical differences between C++ and VBA that need to be accounted and adjusted for, and it will take time to work out.  A couple that have already come to mind include:

  • VBA does not support unsigned number data types
  • C++ allows overflow of number data types and discards the overflow, VBA does not and throws an error

I'm sure there will be other considerations I am not thinking of right now...


»bp
Test your restores, not your backups...
Expert of the Year 2019
Top Expert 2016
Commented:
Okay, in a quick test here this seems to work and calculates the same result as the C++ example you posted.

Option Explicit

Sub Test()
    Dim data() As Byte
    Dim crc As Long

    data = StrConv("0123456789", vbFromUnicode)
    crc = cal_crc(data, 10)
    Debug.Print crc
End Sub

Private Function cal_crc(ptr() As Byte, size As Integer) As Long
    Dim i As Byte
    Dim crc As Long
    Dim ptrIndex As Long

    crc = 0

    For ptrIndex = 0 To size - 1
        i = &H80
        Do While i <> 0
            If (crc And &H8000&) <> 0 Then
                crc = (crc * 2) And &HFFFF&
                crc = crc Xor &H18005
            Else
                crc = (crc * 2) And &HFFFF&
            End If
            If (ptr(ptrIndex) And i) <> 0 Then
                crc = crc Xor &H18005
            End If
            i = i / 2
        Loop
    Next ptrIndex

    cal_crc = crc And &HFFFF&
End Function

Open in new window


»bp
Dear Bill Prew


Thank you so much for a great job well done , this has a big headache for me and now its over.

Regards

Chris