1. ## Bitwrap

Good day,

I'm attempting to write a short encryption program. One stage of the encryption / decryption process will be bitshifting. However, this process ( using << and >> operators ) causes data corruption : the end bit is lost. I wish to make sure that, whether the bit added when the program is run, is a 0 or a 1, that my code will work. Therefore, I have put together the following program :

THEORY :

Encryption
Left bitshift by 1 bit. Endbit is lost. If endbit ( left bit representing 128 ) is 1, the value of character is bigger than 127. Therefore, if this is the case, bitshift 1 left, and then OR the value with the integer 1 ( 00000001 ) to wrap this bit on the end. This will correct the bitshift, whether the added bit on the right is a 1 or a 0.
If the value of the character is less than 128, then bitshift left, and check if this new value is odd. If it is, take away 1, else, do nothing. This will correct the value of the bitshifted char, whether the added bit was 1 or 0.

Decryption
Right bitshift by 1 bit. Endbit ( right bit representing 1 ) is lost. If the value of the character is odd, then the endbit = 1. In this case, bitshift right, and check if the new value is larger than 127. If so, the added bit was 1, so do nothing. If it is less than 128, add 128 to the ASCII value in order to turn the added bit to 1.
If the value is even, the new bit must be 0. Therefore, check, as above, if the new value, once bitshifted, is larger than 127. If this is the case, subtract 128. Else, do nothing. This will make sure the added bit is 0.

PRACTICE :
Code:
```void bse()   // BitShift Encrypt
{
int b = (int)a;   // a is char a; the character being encrypted.

if(b > 127)
{
a = (a << 1);
a = (a | 1);
}

else if(b < 128)
{
a = (a << 1);
if(a % 2 == 1) a = a - 1;
}
}

void bsd()    // BitShift Decrypt
{
int b = (int)a;

if((b % 2) == 1)
{
a = (a >> 1);
int c = (int)a;
if(c < 127) a = a + 128;
}

else if((b % 2) == 0)
{
a = (a >> 1);
int c = (int)a;
if(c > 127) a = a - 128;
}
}```

For some reason that escapes me, this code only works for ASCII values larger than 127, and I cannot see the problem...

Korhedron

2. Might be wrong, but isnt it always a 0 thats added in bit shift?

3. I haven't studied your code thoroughly, but something's weird here:
Code:
```a = (a << 1);
if(a % 2 == 1) a = a - 1;```
After you bit-shift left, the number will always be even. You are probably supposed to perform the full bit-rotate here, not just a bit-shift.

The assignment-instructions are almost step-by-step psudo code... If this was my assignment, I would split-up the instructions (one line per instruction) and copy them into the program as comments. That would make it easier to see if the code really follows the logic.

4. Code:
`b = ((b<<1)&0xFE) | ((b>>7)&0x01);`

5. Thank you for all the replies...

I still have a few questions.
Firstly, RedZone, I thought that 0 was always added, yet the code above is supposed to be able to work whether a 0 or a 1 was added... When bitshifting left, the test determines whether the lost bit was 1 or 0, and then makes sure the added bit corresponds. When bitshifting right, the same thing is done : the lost bit is determined, and then we make sure the added bit corresponds. Therefore, why does this only work for ASCII values above 128 ?

DougDBug, thanks for the comments. I'm aware that my code is hardly presentable :P

Salem, thanks for the alternative, which I'm still trying to work out

I'll post my progress as soon as possible.

Thanks,
Korhedron

6. The code seems to work, except now, for values above 128. I think this is because my tests have been using Notepad, which won't take Unicode characters ( and, for example, the character é which has an ASCII value of 130, bitwraps left to have an ASCII value of 5, which Notepad won't take ). However, I've tested this with MSWord Documents, or with JPG images, and still, the outputted file has changes and won't open properly. I'm not sure what's going wrong...

Currently, I'm doing this :

Code:
```void bse()
{
int b = (int)a;
if(b > 127)
{
a = ((a << 1) | 0x01);  // If the lost bit was 1, make sure it's 1 on the right after bitshift
}

else
{
a = ((a << 1) & 0xFE);   // If lost bit was 0, make sure it's 0 after bitshift
}
}

void bsd()
{
if( ((int)a) % 2 == 1)
{
a = ((a >> 1) | 0x80);
}

else
{
a = ((a >> 1) & 0x7F);
}
}```

I'm therefore thinking the code works, but file formats won't take certain characters. I've tried files with no extension, same problem : chars with ASCII over 128 won't convert properly... Any ideas ?

Thanks,
Kor

7. Code:
`b = ((b<<1)&0xFE) | ((b>>7)&0x01);`
This is not hard to work out at all. Lets split it up a little.

whats the bit pattern of 0xFE?
it looks like this....
11111110
This is a mask. First b is left shifted 1 bit. That means each bit is moved up into the next highest bit and a zero is placed in the least significant bit. The most significant bit is lost.We then bitwise and the temporary that holds our bitshifted b with the mask.This has the effect of preserving the top 7 bits and clearing the least significant bit.
Now the other side of the or. This time we make a temporary with the most significant bit shifted all the way to become the least significant bit. We then and it with this bit pattern....
00000001
This clears the top seven bits and preserves the least significant bit(which used to be the msb).
Finally the shifted left 1 place temporary is binary ored with the temporary that holds our msb shifted to lsb.This has the effect of combining the two halfs. Finally that result is assigned to b.
This does a byte bit rotation.

8. Stoned_Coder, thanks for the explanation, I had missed the fact that all bits except the least significant bit would be cleared in the second part.

This solves my problem, and is by far a more efficient way of bitwrapping my characters. However, it seems this will still cause a problem : I cannot use this to encrypt data, as certain ASCII values aren't characters but control keystrokes ( such as '\a' which cannot be printed in a file ). I was therefore wondering if anyone knew a way to solve this problem, to be able to use bitwrapping in an encryption algorithm...

Thanks for everyone's help !
Korhedron

9. Use binary i/o not text i/o

10. I am currently using binary I/O, still to the same effect... é ( ASCII 130 ) becomes ASCII 5 which won't print or save to file.

11. post your i/o routines. Lets see whats going on.

12. Code:
```ifstream fin;
ofstream fout;

fin.open("text.txt", ios::binary);
fout.open("out.txt", ios::binary);

while(fin.get(a))
{
bse();
fout << a;
}```
That's all I'm doing... I've tried with files with no extension, to the same result.

13. Originally Posted by Korhedron
Code:
`if(a % 2 == 1) a = a - 1;`
this is the same as this
Code:
`a &= ~1;`
in words, if there's a less significant 1, change it to zero, always

Originally Posted by Korhedron
Code:
```ifstream fin;
ofstream fout;

fin.open("text.txt", ios::binary);
fout.open("out.txt", ios::binary);

while(fin.get(a))
{
bse();
fout << a;
}```
That's all I'm doing... I've tried with files with no extension, to the same result.
Code:
```void bse(int& a)
{
a = ((a<<1) &0xfe )| ( (a>>7) &1 );
}

void bsd(int& a)
{
a = ((a>>1) &0x7f )| ( (a<<7) &0x80 );
}

/*********************************/
ifstream fin;
ofstream fout;

fin.open("text.txt", ios::binary);
fout.open("out.txt", ios::binary);

while(fin.get(a))
{
bse(a);
fout << a;
}```

14. > the character é which has an ASCII value of 130, bitwraps left to have an ASCII value of 5, which Notepad won't take
Yeah, you really need a hex editor to view the output files of your program to stand any chance of seeing what's happening.
That way, you can see what each byte really is.

15. Thanks for the help, I'll get a hex editor. Other than that though, I can't really use this in any kind of algorithm, or I'd have some kind of data loss if I compensated for unprintable characters... Thanks anyway

xErath, my char a is a global variable, thus is passed to the function when it calls it.

Thanks a lot,
Korhedron