By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,564 Members | 804 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,564 IT Pros & Developers. It's quick & easy.

c to java CRC32 code conversion

P: n/a
Hi,

I am attempting to convert the following code written in c to
equivalent java code. This is the CRC32 algorithm used by a GPS
received I am interfacing with. Unfortunately, the CRC32 class
provided in the java API does not suit my needs because it does not
allow manipulation of the polynomial being used. Below is the original
c-code followed by my attempt to convert the code to java.
Unfortunately, my code does not produce the correct results. I assume
I am missing something in regards to the data types I am using,
specifically the change from unsigned long in c to a java int, or
something in the bit-shift operations. Any insight you can provide
would be helpful. Thanks.

c-code********************************

#define CRC32_POLYNOMIAL 0xEDB88320L
/*
--------------------------------------------------------------------------
Calculate a CRC value to be used by CRC calculation functions.
--------------------------------------------------------------------------
*/
unsigned long CRC32Value(int i)
{
int j;
unsigned long ulCRC;
ulCRC = i;
for ( j = 8 ; j > 0; j-- )
{
if ( ulCRC & 1 )
ulCRC = ( ulCRC >> 1 ) ^ CRC32_POLYNOMIAL;
else
ulCRC >>= 1;
}
return ulCRC;
}

/*
--------------------------------------------------------------------------
Calculates the CRC-32 of a block of data all at once
--------------------------------------------------------------------------
*/
unsigned long CalculateBlockCRC32(
unsigned long ulCount, /* Number of bytes in the data block */
unsigned char *ucBuffer ) /* Data block */
{
unsigned long ulTemp1;
unsigned long ulTemp2;
unsigned long ulCRC = 0;
while ( ulCount-- != 0 )
{
ulTemp1 = ( ulCRC >> 8 ) & 0x00FFFFFFL;
ulTemp2 = CRC32Value( ((int) ulCRC ^ *ucBuffer++ ) & 0xff );
ulCRC = ulTemp1 ^ ulTemp2;
}
return( ulCRC );
}
java code ************************************************

private static final int CRC32_POLYNOMIAL = 0xEDB88320;
/*
--------------------------------------------------------------------------
Calculate a CRC value to be used by CRC calculation functions.
--------------------------------------------------------------------------
*/
private static int CRC32Value(int i)
{
short j;
int ulCRC;
ulCRC = i;

for (j = 8; j > 0; j--) {
if ((ulCRC & 1) == 1)
ulCRC = (ulCRC >>> 1) ^ CRC32_POLYNOMIAL;
else
ulCRC >>>= 1;
}
return ulCRC;
}

/*
--------------------------------------------------------------------------
Calculates the CRC-32 of a block of data all at once
--------------------------------------------------------------------------
*/
public static int calculateCRC32(int length, byte[] buffer)
{
int ulTemp1;
int ulTemp2;
int ulCRC = 0;

for(int i = 0; i < length; i++) {
ulTemp1 = ( ulCRC >>> 8 ) & 0x00FFFFFF;
ulTemp2 = CRC32Value( ((int) ulCRC ^ buffer[i] ) & 0xff );
ulCRC = ulTemp1 ^ ulTemp2;
}
return ulCRC;
}

Jul 17 '05 #1
Share this Question
Share on Google+
1 Reply


P: n/a

Looks like it works to me.

I built the following test case based on the output of a simple C
driver program. A test case necessary to determine what we are
talking about here.

import junit.framework.TestCase;

public class TestCRC32 extends TestCase {
public void test1() {
CRC32 t1 = new CRC32();
byte[] buf = new byte[20];
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (i * 511);
}
assertEquals(0x9d335772, t1.calculateCRC32(buf));
t1.reset();
t1.calculateCRC32(buf, 0, 10);
assertEquals(0x9d335772, t1.calculateCRC32(buf, 10, 10));
}
}

This code computes the crc in a single pass and in an incremental
fashion to show off some increased flexibility in the new code.

I also adapted your code slightly so that you can create a CRC object
that remembers its state and so that the polynomial can be reset. I
also modified it to match normal Java coding standard a bit closer.
Hungarian notation is really just an affectation in Java; it was
necessary in assembler and in poorly typed environments such as the
win32 API, but is not useful in Java. Also, it is helpful if you
follow Javadoc style.
/**
* Implements a general CRC class that lets you change the polynomial.
*/
public class CRC32 {
private int polynomial = 0xEDB88320;
private int crc = 0;

/**
* Calculates a CRC value for a byte to be used by CRC calculation
functions.
*/
private int CRC32Value(int i) {
int crc = i;

for (int j = 8; j > 0; j--) {
if ((crc & 1) == 1)
crc = (crc >>> 1) ^ polynomial;
else
crc >>>= 1;
}
return crc;

}

/**
* Calculates the CRC-32 of a block of data all at once
*/
public int calculateCRC32(byte[] buffer, int offset, int length) {
for (int i = offset; i < offset + length; i++) {
int tmp1 = (crc >>> 8) & 0x00FFFFFF;
int tmp2 = CRC32Value(((int) crc ^ buffer[i]) & 0xff);
crc = tmp1 ^ tmp2;
}
return crc;
}

/**
* Calculates the CRC-32 of a block of data all at once
*/
public int calculateCRC32(byte[] buffer) {
return calculateCRC32(buffer, 0, buffer.length);
}

/**
* Resets the state to process more data.
*/
public void reset() {
crc = 0;
}

public void setPolynomial(int polynomial) {
this.polynomial = polynomial;
}
}

Jul 17 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.