//------------------------------------------------------------------- // xsumdemo.cpp // // This program illustrates the advantages of one's complement // addition for computing of checksums in network programming. // // compile using: $ g++ xsumdemo.cpp -o xsumdemo // execute using: $ ./xsumdemo // // programmer: ALLAN CRUSE // written on: 26 MAR 2008 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #include // for htons() #define BUF_LEN 64 unsigned char packet[ BUF_LEN ]; int main( int argc, char **argv ) { // initialize an array of bytes with random values for (int i = 0; i < BUF_LEN; i++) packet[ i ] = (unsigned char)rand(); // display the array in hexadecimal format printf( "\n Sample packet-array of random data is shown below: \n" ); for (int i = 0; i < BUF_LEN; i++) { if ( ( i % 16 ) == 0 ) printf( "\n %04X: ", i ); printf( "%02X ", packet[ i ] ); } printf( "\n\n" ); // compute the normal 16-bit two's complement sum // using the CPU's native 'little endian' byte-order unsigned short *wp = (unsigned short*)packet; unsigned int sum = 0; for (int i = 0; i < BUF_LEN / 2; i++) sum += wp[i]; sum &= 0xFFFF; printf( "\n The 16-bit little-endian two's complement sum " ); printf( "is %04X \n", sum ); // recompute this sum using the network 'big endian' byte-order sum = 0; for (int i = 0; i < BUF_LEN / 2; i++) sum += htons( wp[ i ] ); sum &= 0xFFFF; sum = htons( sum ); printf( "\n The 16-bit big-endian two's complement sum " ); printf( "is %04X \n", sum ); printf( "\n" ); // now compute the 16-bit one's complement sum // using the CPU's native 'little endian' byte-order sum = 0; for (int i = 0; i < BUF_LEN / 2; i++) sum += wp[i]; sum += (sum >> 16); sum &= 0xFFFF; printf( "\n The 16-bit little-endian one's complement sum " ); printf( "is %04X \n", sum ); // recompute this sum using the network 'big endian' byte-order sum = 0; for (int i = 0; i < BUF_LEN / 2; i++) sum += htons( wp[ i ] ); sum += (sum >> 16); sum &= 0xFFFF; sum = htons( sum ); printf( "\n The 16-bit big-endian one's complement sum " ); printf( "is %04X \n", sum ); printf( "\n" ); // display the concluding observation printf( "\n These comparisons show us why the one's complement " ); printf( "\n checksum is preferred as being \'endian neutral\'. " ); printf( "\n\n" ); }