1

I want to take a 1s complement of whatever bits are there in sum+ and save the complemented bits in finalsum. how to do that. I am a bit weak with using bitvec and uint32_t type stuff. so i am confused here. please help.

#include <iostream>
#include <string>
#include <bitset>
using namespace std;
#include <vector>
#include <stdint.h>

int main() {
int i;
string j;

std::string message = "hello "; // Some string.
std::vector<uint16_t> bitvec;
unsigned char* cp = message.c_str()+1;
while (*cp) {
   uint16_t bits = *(cp-1)>>8 + *(cp);
   bitvec.push_back(bits);
}

uint32_t sum=0;
uint16_t overflow=0;

for(auto j = bitvec.begin(); j != bitvec.end(); ++j) { 
sum += *j;
std::uint16_t; overflow = sum>>16;  //capture the overflow bit, move it back to lsb
sum &= (1<<16)-1;    //clear the overflow
sum += overflow;     //add it back as lsb
}

uint32_t finalsum=0;
for (k=0; k<=sum.length(); k++)
{finalsum = !(sum[k])]
}

cout << finalsum ;
return 0;

}
user899714
  • 455
  • 6
  • 13
  • 23
  • i am getting an error too of invalid conversion from constant char to unsigned char in this line: unsigned char* cp = message.c_str()+1; – user899714 Nov 09 '13 at 09:44
  • Declare the pointer as `const char *`, and use `(0xFF & *cp)` and `(0xFF & *(cp - 1))` instead. – Joe Z Nov 09 '13 at 09:51
  • 2
    Why don't you just use the `~` operator? That does exactly this. –  Nov 09 '13 at 09:52
  • @ Joe Z: i am getting this error: [Error] invalid type argument of unary '*' (have 'int') this way – user899714 Nov 09 '13 at 10:11

1 Answers1

3

It looks like you're trying to implement something like TCP's 1s complement checksum.

// Compute the sum.  Let overflows accumulate in upper 16 bits.
for(auto j = bitvec.begin(); j != bitvec.end(); ++j) 
    sum += *j;

// Now fold the overflows into the lower 16 bits.  This requires two folds, as the
// first fold may generate another carry.  This can't happen more than once though.
sum = (sum & 0xFFFF) + (sum >> 16);
sum = (sum & 0xFFFF) + (sum >> 16);

// Return the 1s complement sum in finalsum
finalsum = sum;

This should do the trick.

On a separate note, I think you need a cp += 2 somewhere in this loop:

while (*cp) {
    uint16_t bits = *(cp-1)>>8 + *(cp);
    bitvec.push_back(bits);
    cp += 2;  // advance to next pair of characters
}

That loop will also fail if your input string isn't an even number of characters, so consider rewriting it more robustly...

Joe Z
  • 17,413
  • 3
  • 28
  • 39
  • yes it is a kind of tcp checksum. and even if the string is odd, shouldnt the space at the end of the string \0 thing make it even? – user899714 Nov 09 '13 at 10:03
  • i dont really understand the cp+2 thing ur suggesting – user899714 Nov 09 '13 at 10:06
  • You need to iterate through the characters. The while loop you shared with us will iterate forever but not advance through the characters. – Joe Z Nov 09 '13 at 10:08
  • As for odd vs. even: Your initial while loop steps by pairs of characters, but only tests one character of each pair for the terminating NUL. Walk through an example with an even-length string and an odd length string, and see if either causes the while loop to read beyond the end of string. – Joe Z Nov 09 '13 at 10:11
  • the odd doesnt, because that is what i was testin it with. – user899714 Nov 09 '13 at 10:14
  • another issue is: i get a sum value which is in integers, although i wanted a binary sum at the end :( in the form of 0's and 1's (16 bits) – user899714 Nov 09 '13 at 10:17
  • Printing the sum as 1s and 0s is a printing problem, not a computation problem. You might take a look at this other answer for how to print your result: http://stackoverflow.com/questions/7349689/c-how-to-print-using-cout-the-way-a-number-is-stored-in-memory – Joe Z Nov 09 '13 at 18:08
  • Many thanks @JoeZ! This helps me a lot to learn to implement a 1's complement checksum. – Gabriel Staples Aug 18 '16 at 02:25