Jump to content
  • Advertisement
Sign in to follow this  

This topic is 4235 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am maintaining existing code and a problem has occured with the existing CRC32 algorithm. If a CRC32 is calculated for a file that ends in a CRC32 the new CRC32 is always 0x38FB2284. I have compared the code to examples I have found on various websites and the following line seems to be to blame: return ( ( aCrc << 8 ) ^ CRC_32_LOOKUP_TABLE[ aByte ^ ( aCrc >> 24 ) ] ); I believe the following line is correct: return ( ( aCrc >> 8 ) ^ CRC_32_LOOKUP_TABLE[ aByte ^ ( aCrc &0xFF ) ] ); Has anyone seen a similar situation or any reason that the first line above is correct. I have to convince my supervisor that the CRC algorithm they have been using for the past year is incorrect. H

Share this post


Link to post
Share on other sites
Advertisement
Quote:
... If a CRC32 is calculated for a file that ends in a CRC32 the new ...


What does "ends in a CRC32" mean? Appended? To a binary file? ...

How you shift the checksum is irrelevant, left or right only depends on your particular implementation, and possibly byte order.

Share this post


Link to post
Share on other sites
Instead of comparing the values between your algorithm and itself, you should find another implementation (google code search for some of the values in your lookup table to find implementations using the same base algorithm - wikipedia says there are several different "CRC32") and compare the output of your version to those.

Share this post


Link to post
Share on other sites
By ends in CRC32 I mean the following:

One of our tools is used to concatenate several files into 1 file. This tool calculates CRC32 for each file it adds and saves these CRC32 values in a header. Some of the files that are added already have CRC32 appended to the end while others do not. All of the files that have a CRC32 appended to the end have the same CRC32(0x38FB2284). The table was generated using the standard ethernet key( 0x04C11DB7 not reflected though). I am fairly certain there is an error since it is easy to create many different files that all have the same CRC according to the current code.

Share this post


Link to post
Share on other sites
I was told some time ago that one method of checking the CRC is to pass the CRC itself through the algorithm as well, and you always get the same result.
The same thing more obviously works for checksums of course, but at the time I never realised it would also work for CRC.

So I'm 95% sure that this is correct behaviour. Also, it in no way reduces the integrity of the data, so there is nothing to worry about.

Share this post


Link to post
Share on other sites
When I use other CRC tools this does not happen. It has been brought to my attention that the algorithm in use is different than standard CRC32 since it is used to create CRC values for use on PPC systems and thus big-endian. It still seems to be incorrect for all files with the CRC32 appended to the end to generate the fixed CRC = 0x38FB2284.

Share this post


Link to post
Share on other sites
Well, rather than playing the guessing game:
1) The checksum calculation algorithm is implemented incorrectly
2) A calculation problem occurs due to type casting, byte-ordering or shifting
3) CRC table is incorrectly initialized, or not initialized at all
3) The algorithm is called incorrectly and doesn't calculate checksum for the file
4) The data written as checksum isn't checksum

3 and 4 are also very likely.

Now you can post the code, the example of how it's used, how it's written, or something else.

But beyond that, nobody can help you with this. The problem is trivial.
- Initialize checksum
- Read bytes from file and update checksum with them
- Write the checksum to file

But where the error lies is a matter of going through the code. There is no fundamental flaw here. It's just a matter of finding a bug.

Share this post


Link to post
Share on other sites
A search for 38FB2284 yielded results.
Copied from rfc282 :
The CRC-32 on the payload data (used for PPP over SDL) uses the
initial remainder value of FFFFFFFF hex for calculation and the bits
are complemented before transmission. The CRC, however, is
transmitted in network byte order, most significant bit first, unlike
the optional PPP 32 bit FCS, which is transmitted in reverse order.
The remainder value on intact packets when the appended CRC value is
included in the calculation is 38FB2284.

So it turns out iMalc was correct. I was able to reproduce with a windows CRC program that uses little-endian by appending the CRC value with the byte order reversed. The little-endian files all had the CRC value 2144DF1C. If you search for either 2144DF1C or 38FB2284 you will see many results about correctly received packets. I feel really stupid now for not seeing this earlier. So I was wrong the algorithm was correct all along. Sorry to waste everyones time.

Harry Kuhar

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!