Saturday, October 10, 2009

[vobzjaio] checksum

A simpler implementation of the POSIX cksum program, calculating CRC32 big-endian, not using a lookup table. This is slower, but may be useful pedagogically.

#include <cstdio>
typedef unsigned int U32;
const U32 polynomial=0x04C11DB7;
void update_crc(U32 *rem, unsigned char in){
*rem^=in<<24;
for(int j=0;j<8;++j){
U32 top_bit=*rem&0x80000000;
*rem<<=1;
if(top_bit)*rem^=polynomial;
}}

int main(){
U32 rem=0;
long long bytecount=0;
for(;;++bytecount){
unsigned char in;
int code=fread(&in,1,1,stdin);
if(1!=code)break;
update_crc(&rem,in);
}
//append the length, LSByte first
for(long long datalength=bytecount;datalength;datalength>>=8){
update_crc(&rem,datalength); //auto-truncate U32 to byte
}
rem=~rem; //seems a bit superfluous, given we are appending the length
printf("%u %lld\n",rem,bytecount);
}

No comments :