c to java CRC32 code conversion

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • PaullyB

    #1

    c to java CRC32 code conversion

    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_POLYNOMIA L 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_POLYNOMIA L;
    else
    ulCRC >>= 1;
    }
    return ulCRC;
    }

    /*
    --------------------------------------------------------------------------
    Calculates the CRC-32 of a block of data all at once
    --------------------------------------------------------------------------
    */
    unsigned long CalculateBlockC RC32(
    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_POLYNOMIA L = 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_POLYNOMIA L;
    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;
    }

  • Ted Dunning

    #2
    Re: c to java CRC32 code conversion


    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(0x 9d335772, t1.calculateCRC 32(buf));
    t1.reset();
    t1.calculateCRC 32(buf, 0, 10);
    assertEquals(0x 9d335772, t1.calculateCRC 32(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(((in t) 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(i nt polynomial) {
    this.polynomial = polynomial;
    }
    }

    Comment

    Working...