?
Solved

Code translation C to VB problem

Posted on 2006-05-12
16
Medium Priority
?
646 Views
Last Modified: 2013-11-12
I am attempting to recreate a bit of C code into VB code however it is not cooperating. I have sample input and output of what the results should be in C lanugage but I have been unable to make a function in VB6 which will emulate the action. Simply put, I need to create a 16 bit CRC CCITT check that will produce the following...

'// The following code is what I intend to accomplish with actual inputs and actual results in VB6
'//BEGIN
B(0) = 0
B(1) = 88
By(2) = 1

s = CRC16(b)

s = "47EB"
'//END

'// The following code is what I have been provided with in C language


// BEGIN
unsigned short CRC(unsigned char *s, int len, unsigned
short crcv)
{
register unsigned c,q;
for (; len; len--)
{
c = *s++;
q = (crcv ^ c) & 017;
crcv = (crcv >> 4) ^ (q * 010201);
q = (crcv ^ (c >> 4)) & 017;
crcv = (crcv >> 4) ^ (q * 010201);
}
return (crcv);
}
//END

'// So far I have been unable to get any translated code to work in VB6, I always get overflows. I am not skilled with C languages unfortuantly.
'// Any help would be greatly appreciated
0
Comment
Question by:HRCIII
16 Comments
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671538
Hi HRCIII,

I'm no VB expert but I can interpret the C for you:

// Ignore 'register'. c and q are integers.
register unsigned c,q;

// Count 'len' down to zero, repeating the contents of the brace.
for (; len; len--)
{
// Collect the next character into 'c'.
c = *s++;
// q = (crcv xor c) bitwise anded with octal 17 (hex 0f, decimal 15).
q = (crcv ^ c) & 017;
// crcv becomes (crcv bitshifted right 4 bits) xor (q * octal 10201),
crcv = (crcv >> 4) ^ (q * 010201);
// q = ( crcv xor ( c bitshift right 4 bits ) ) bitwise anded with octal 17 (hex 0f, decimal 15)
q = (crcv ^ (c >> 4)) & 017;
// Same process as above.
crcv = (crcv >> 4) ^ (q * 010201);
}
// result of function is crcv.
return (crcv);
}


Paul
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671553
Hi HRCIII,

The difficulty you will have is matching the exact number of bits of the original algorithm. I cant see anything that suggests a 32 bit architecture but its certainly 16bit or more because octal  010201 is 16 bits wide.

Paul
0
 

Author Comment

by:HRCIII
ID: 16671566
I VB very well but I know little to nothing about C, if it helps, the input data as viewed in hex comes in as three bytes like this..
'01 58 00'
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671592
Hi HRCIII,

Ok! You be the VB guru (is there a song in that?) and throw something together that does what my comments describe and between us we'll crack it. I know enough VB to read it but I dont write it too quickly.

Paul
0
 

Author Comment

by:HRCIII
ID: 16671623
Unfortuantly I cant spell or do grammer either :).

Using the following function I still have an Overflow error occurring. I am calling the function using the following example code.


'///// Calling code using a command button //////
Private Sub cmdTestCRC_Click()
   
    Dim s, n As Integer
    Dim b(2) As Byte
   
    b(0) = 1
    b(1) = 88
    b(2) = 0
   
    s = CRC16(b, n)
   
    MsgBox s

End Sub
'///////////////// END ///////////


Function CRC16(ByRef s() As Byte, ByVal crcv As Integer) As Integer
Dim c As Byte, q As Long
Dim i As Integer
  For i = LBound(s) To UBound(s)
  c = s(i)
 q = (crcv Xor c) And &O17&
 crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&
 q = (crcv Xor Fix(c / 16)) And &O17&
 crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&
 Next i
 CRC16 = crcv
 End Function
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671635
Hi HRCIII,

Where does it overflow?

Looks like what you've got is close. I cant see any problems with at first sight.

Paul
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671656
 Dim b(2) As Byte
   
    b(0) = 1
    b(1) = 88
    b(2) = 0

Can you do that in VB? Create an array length 2 and put 3 items in it? Or is that an array of length 3?

Paul
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16671672
Erm...

  Dim s, n As Integer
    Dim b(2) As Byte
   
    b(0) = 1
    b(1) = 88
    b(2) = 0
   
    s = CRC16(b, n)
 
You dont seem to have initialised 'n'. Surely it should be 3?

Paul
0
 

Author Comment

by:HRCIII
ID: 16671823

Function CRC16(ByRef s() As Byte, ByVal crcv As Integer) As Integer
Dim c As Byte, q As Long
Dim i As Integer
  For i = LBound(s) To UBound(s)
   c = s(i)
   q = (crcv Xor c) And &O17&
  crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&   '//OVERFLOW ON THIS LINE
 q = (crcv Xor Fix(c / 16)) And &O17&
 crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&
 Next i
 CRC16 = crcv
 End Function
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 16673181
Write C code to Dll and call it using VB API calls feature. If something is working, don't touch it.
0
 
LVL 16

Assisted Solution

by:PaulCaswell
PaulCaswell earned 200 total points
ID: 16673404
>>  crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&   '//OVERFLOW ON THIS LINE
To find out where dosomething like:
a = Fix(crcv / 16)
b = q * &O10201&
c = a Xor b
d= c And &HFFFF&

Which line overflows?

Paul
0
 

Author Comment

by:HRCIII
ID: 16674108

I highlighted the line which overflowing below...


Function CRC16(ByRef s() As Byte, ByVal crcv As Integer) As Integer
Dim c As Byte, q As Long
Dim i As Integer
  For i = LBound(s) To UBound(s)
       c = s(i)
       q = (crcv Xor c) And &O17&
>>  crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&  
       q = (crcv Xor Fix(c / 16)) And &O17&
       crcv = Fix(crcv / 16) Xor (q * &O10201&) And &HFFFF&
 Next i
 CRC16 = crcv
 End Function
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 16674266
So its one of the calculations in that expression. My suggestion should find out which one.

Paul
0
 

Author Comment

by:HRCIII
ID: 16677503
I would gladly use API calls to a DLL containing the function but I have no capability for accomplishing this, I would gladly pay someone to take care of it, unfortunatly I don't know anyone who can.
0
 
LVL 2

Accepted Solution

by:
mackenga earned 400 total points
ID: 16725747
Got it - I've not gone into any details here, but I can see what is causing your overflow.  Where C uses a shift operator, your VB code is using multiplication.  This is fundamentally the right way to simulate a shift in VB (for a shift of n bits, multiply by two to the power of n).  The problem you're having is that when C does a shift it doesn't care about any overflow - C doesn't care much about overflows in fact, and leaves that up to the programmer.  In VB, the overflow is an error.

I couldn't tell you off the top of my head whether VB leaves the right (truncated) value in the integer variable after the overflow - if it does, you can ignore the error with something like 'on error resume next' and just check to ensure that it's an overflow getting thrown that you don't care about.  If VB doesn't leave the right truncated value on an overflow, try storing the result in a long and truncating it yourself with a bitwise and.

Hope this helps - looks like an interesting problem!
0
 
LVL 9

Assisted Solution

by:lojk
lojk earned 400 total points
ID: 16770221
An integer in VB6 is inherently only a signed 15bit number (0+/-32767) so its quite likely you are going to get overflows.

The thread above does spin off into some detail and unfortunately i dont have time to decipher it all now, however dont forget that VB6 does have a 64bit (double and currency) type that may allow better handling of the numbers without overflows, especially if you are trying to shift bits of a 32bit number left or right.

once you have shuffled your bits you can then split your 64bit numbert into hex, cstring it and only retain the last 4 chars..
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article explores the design of a cache system that can improve the performance of a web site or web application.  The assumption is that the web site has many more “read” operations than “write” operations (this is commonly the ca…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question