Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Compute CRC16 IBM / BUYPASS for Foxpro solution 1

Status
Not open for further replies.

boby67

Programmer
Jul 2, 2021
4
0
0
RO
Hello,
I need help for a Foxpro CRC16 compute for a hexa string like :
A0000101
The CRC16 /Buypass for this string is 06 35
i have 2 examples :
Java:
Java implementation

public class CRC {
private static final int CRC_POLYNOM = (int) 0x00008005;
private static final int CRC_MASK = (int) 0x00008000;
public static int CalculateCRC(byte[] buffer, int length) {
 int crc = 0x00000000;
 for (int i = 0; i < length; i++) {
   crc ^= (int) ((buffer[i] << 8) & 0x0000FFFF);
      for (int j = 0; j < 8; j++) {
        if ((crc & CRC_MASK) == CRC_MASK) {
            crc <<= 1;
            crc = crc ^ CRC_POLYNOM;
        } else {
            crc <<= 1;
        }
        crc &= 0x0000FFFF;
      }
   }
   return crc;
   }
}
--------------------------------
Code:
VB implementation

Public Function CRCCalculator(data() As Byte) As UShort
Dim crc As UShort = &H0&
Dim tmp As UShort = &H0&
Dim i As Long
Dim j As Long
For i = 0 To data.Length() – 1
  tmp = data(i) * &H100&
  crc = crc Xor tmp
  For j = 0 To 7
    If (crc And &H8000&) Then
      crc = ((crc * 2) Xor &H8005&) And &HFFFF&
    Else
      crc = (crc * 2) And &HFFFF&
    End If
  Next j
Next i
CRCCalculator = crc And &HFFFF
End Function

I try this but i'm stuck :
Code:
LPARAMETERS tcString
LOCAL i, nbx, hlp
LOCAL crc as Byte
FOR i=1 TO LEN(tcString)
  tmp=SUBSTR(tcstring,i,1) && CHR(0x1000) ...?
  crc=BITXOR(crc,tmp)
  FOR j=0 TO 7
     IF BITAND(crc,0x8000) <> 0
       crc=BITXOR(crc,0x8005)
     ELSE
       crc=BITAND(crc,0xffff)
     ENDIF
  ENDFOR
ENDFOR
RETURN TRANSFORM(crc,'@0x')
I verify the calculation for that string on to CRC16/BUYPASS and is corect
I have also other examples in C++

Thank you very much for help!
 

mcrc = SYS(2007,"A0000101") && returns CRC16
mcrc = SYS(2007,"A0000101",1) && returns CRC32

Though VFP documents it a checksum but it returns either CRC16/CRC32 . Refer to VFP Help file.


 
It is not the same calculation

for "A0000101" CRC16 is 06 35
for "A0000103" CRC16 is 86 3A
for "A0020352" CRC16 is 0B F7

it is not very different procedure.

Thank you
 
If I use your input in crccalc.com I only get the results you posted when the input is set to HEX.

So the first error is trying to create a crc1 from 'A000101' etc, your input is 0xA0000101 or, easier to generalize for longer input values, you use VFPs varbinary data type and your input then is 0hA0000101, etc.

Your translation didn't implement crc*2 and has several other problems. For example, you didn't know what * 0x100 would do. Just multiplies by 256.

Here's what I got after a bit of try & error:

Code:
Clear

? crc16_buypass(0hA0000101)
? crc16_buypass(0hA0000103)
? crc16_buypass(0hA0020352)

Function crc16_buypass(tcString)
   Local i, j
   Local crc

   crc = 0
   For i=1 To Len(tcString)
      tmp = Asc(Substr(tcString,i,1))*256
      crc=Bitxor(crc,tmp)
      For j=0 To 7
         If Bitand(crc,0x8000) <> 0
            crc=Bitand(Bitxor(crc*2,0x8005),0xffff)
         Else
            crc=Bitand(crc*2,0xffff)
         Endif
      Endfor
   ENDFOR
   
   Return Transform(crc,'@0')

for testing the hex string you get from the final TRANSFORM(crc,'@0') is okay, but if you want to calculate with numeric output, then simply RETURN crc.

Chriss
 
Hi Cris!
Thank you for your kindly effort to fix my problem.
Yes you're right...i didn't specifies if the string is Hexa...my bad.
I learn something new : 0hA00000... a new prefix
if I had been inspired to turn 0x1000 into a decimal = 256 ..I would have caught on...
I have another ambiguity, it is specified in this CRC16 that it is calculated like this:
CRC16 IBM (MSB, LSB) of the entire data for request
messages.
CRC16 IBM (LSB, MSB) of the entire data for response
messages
Does this explanation have any impact on the function you perform?
Thank you again!
Robert

 
Yes, of course, MSB and LSB is about the byte order,

LSB = least significant byte, MSB = most significant byte.
Aka known as Endianness (big endian, littel endian - see
I think you either build the CRC by processing the data bytes from left or right.

Chriss
 
And what may help to understannd treatment of vawrbinary values:

1. VFP Strings can be looked at as byte arrays, though you have no string[pos] but need substring(string,pos,1)
2. Varbinary allows specifying a byte array as an arbitrary long hex value, ie 0h39383736353433323130 is the same as '9876543210'
3. Many functions intended for strings also work for varbinary, as if it was a string.
4. To get the varbinary equivalent of a string you can use CREATEBINARY(), so CREATEBINARY('9876543210') will be displayed as 0h39383736353433323130
5. The inverse operation, getting a string from a varbinary is not easy to find, if you don't know: ''+0h39383736353433323130 will be displayed as '9876543210'
So again 4+5 in short: [tt]varbinary = Createbinary(string)[/tt] and [tt]string = ''+varbinary[/tt]. A little better to understand is [tt]string=CAST(varbinary as M)[/tt]






Chriss
 
Hi Chris!
Thank you for your patience and for your very clear explanations. it's the only forum that was kind enough to help me so I hope to help someone someday just like you did. Appreciations!
 
Robert,

Good to see that Chris was able to help you (which doesn't surprise me).

You might like to know that the forum has a "Great post" feature which you can use to flag a particularly helpful post. Just click the "Great Post" link in the bottom right corner of the post in question. As well as enabling you to show your appreciation, this also flags up the thread as being particularly helpful, which will be of benefit to anyone searching for the solution to a similar problem.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top