tags:

views:

298

answers:

4

Does this seem correct? I'm trying to port this checksum method from C to Java but the values returned from my Java function are too high. I suspect the way I'm fudging the unsigned int is not correct?

char *Generate( char * buffer, long length ) {

     static char tBuf[4];
     long index;
     unsigned int checksum;

     for( index = 0L, checksum = 0; index < length; checksum += (unsigned int) buffer[index++] );
     sprintf( tBuf, "%03d", (unsigned int) ( checksum % 256 ) );
     return( tBuf );

}

My Java port:

public String generateCheckSum( String value ) {        

    char[] chars = value.toCharArray();        
    long checksum = 0L;

    for( int i = 0; i < chars.length; i++ ) {                 
        checksum += (checksum + (long) chars[ i ]) & 0xFF;
    }

    return String.valueOf( checksum % 256 );
}

Any insight is very much appreciated, thanks

+3  A: 

C++

checksum += (unsigned int) buffer[index++]

Java

checksum += (checksum + (long) chars[ i ]) & 0xFF

There's an extra checksum in there

Jim Garrison
BG4
+1  A: 

Dont you think in your Java code

checksum += (checksum + (long) chars[ i ]) & 0xFF;

should be

checksum += ((long) chars[ i ]) & 0xFF;

?

Also in your C funtion, you are using incorrect format specifier for unsigned int. It should be %u instead of %d.

Prasoon Saurav
A: 

A shorter version

public String generateCheckSum(String value) {        
    int checksum = 0;
    for(char ch : value.toCharArray()) checksum += ch;
    return "" + (checksum & 0xFF);
}

Note: checksum % 256 and checksum & 0xFF don't do the same thing. The first is signed and can return a negative result, the second will not.

Peter Lawrey
A: 

Thank you for all of the feedback, it allowed me to get to my final solution. I'm sure it could be tweaked further but it does produce the desired checksum values.

public Integer generateCheckSum(String value) throws UnsupportedEncodingException {

    byte[] data = value.getBytes("US-ASCII");        
    long checksum = 0L;

    for( byte b : data )  {
        checksum += b; 
    }

    checksum = checksum % 256;

    return new Long( checksum ).intValue();

}
BG4