I'm given a large set of instructions to follow for the algorithm in regards to what functions might be made and such, but I'm very confused with how to (1) and (2) of 1. b) which asks me to set position 2 to the left of the current position by some bits. I don't quite understand if I should be creating new functions to achieve this or if I could use the setBit() function I already made? And if I do need to create new functions, I'm still confused with how to set the bits and what the instructions mean by circling back.
I feel like if I can understand how to do the first set of instructions and get used to figuring out how to set the bit positions, I'll have an easier time doing the rest of the instructions. I understand this is a very loaded question, but I would appreciate any help or hints or a push in the right direction as I'm very lost.
Note: only the main function was given to me. I wrote the getBit, setBit, and clearBit functions but I feel like none of them are applicable to question 1).
Instructions I'm struggling with:
(1) process the counter value, using the key value, as follows:
(a) make a copy of the counter value into a temp counter
(b) for every bit position, starting at bit position 7:
(i) compute two bit positions (position 1 and position 2) that you will use to perform an xor
between two of the temp counter bits: position 1 is set to the current bit position, and
position 2 is computed as follows:
(1) if the key bit at the current bit position is 1, then position 2 is set to one bit
position to the left of the current bit position, assuming we circle back to the
least significant bits (for example, we consider bit 0 to be to the left of bit 7)
(2) if the key bit at the current bit position is 0, then position 2 is set to two bit
positions to the left of the current bit position, assuming we circle back
(ii) xor the two temp counter bits found at positions 1 and 2
main.c
int main()
{
char str[8];
int choice;
printf("\nYou may:\n");
printf(" (1) Encrypt a message \n");
printf(" (2) Decrypt a message \n");
printf("\n what is your selection: ");
fgets(str, sizeof(str), stdin);
sscanf(str, "%d", &choice);
switch (choice) {
case 1:
break;
case 2:
break;
default:
break;
}
return 0;
}
unsigned char swapBitsOne(unsigned char counter, int bitOne, int bitTwo){
/* if the key bit at the current bit position is 1, then position 2 is set to one bit position to
the left of the current bit position, assuming we circle back to the least significant bits (for
example, we consider bit 0 to be to the left of bit 7)
*/
}
unsigned char swapBitsTwo(unsigned char counter, int bitOne, int bitTwo){
/*
if the key bit at the current bit position is 0, then position 2 is set to two bit positions to
the left of the current bit position, assuming we circle back
*/
}
unsigned char processCounter(unsigned char key, unsigned char counter){
unsigned char tempCounter;
strcpy(counter, tempCounter);
int i;
for(i = 7; i >= 0; --i){
if(key == 1){ // if the key bit at the current bit position is 1
counter = setBit(i, 1
}
if(key == 0){
counter = swapBitsTwo();
}
}
return tempCounter;
}
unsigned char getBit(unsigned char c, int n){
return(c & 1 << n) >> n;
}
unsigned char setBit(unsigned char c, int n){
return c | (1 << n);
}
unsigned char clearBit(unsigned char c, int n){
return c & (~(1 << n));
}
You've got a few too many functions, making the solution a bit too complex.
First, you can't use strcpy
on simple char
arguments. You need to pass char *
arguments. But, just use a simple assignment.
In processCounter
...
You need to extract the bit from the key
for the given/current bit position (e.g. unsigned char keybit = getBit(key,i);
).
"Position 1" is always the current position (i.e. i
).
"Position 2" is based on what keybit
is.
You need to get the given bits from c
, based on the two values of pos1
and pos2
.
You need to set/clear the result bit in the output based on the value of the XOR of those two bits.
Anyway, here's some refactored code that does what you need.
Note that I've reversed the order of the c
and key
arguments to be more idiomatic (and consistent with the c
argument for your other [helper] functions).
Also, you don't really need to "copy" the argument c
, just use a different variable for the return value. That's because all eight bits of the result get replaced.
unsigned char
getBit(unsigned char c, int n)
{
#if ORIG
return (c & 1 << n) >> n;
#else
return (c >> n) & 1;
#endif
}
unsigned char
setBit(unsigned char c, int n)
{
return c | (1 << n);
}
unsigned char
clearBit(unsigned char c, int n)
{
#if ORIG
return c & (~(1 << n));
#else
return c & ~(1 << n);
#endif
}
unsigned char
processCounter(unsigned char c,unsigned char key)
{
int curpos;
int pos1;
int pos2;
unsigned char bit1;
unsigned char bit2;
unsigned char xor;
unsigned char out = 0;
for (curpos = 7; curpos >= 0; --curpos) {
// 1.b.i
pos1 = curpos;
// 1.b.i.1
if (getBit(key,curpos))
pos2 = (curpos + 1) % 8;
// 1.b.i.2
else
pos2 = (curpos + 2) % 8;
// 1.b.ii
bit1 = getBit(c,pos1);
bit2 = getBit(c,pos2);
xor = (bit1 ^ bit2) & 1;
if (xor)
out = setBit(out,curpos);
else
out = clearBit(out,curpos);
}
return out;
}
Note that you could replace the final if/else
with:
out |= xor << curpos;
And, you could replace the if/else
for 1.b.i.1 and 1.b.i.2 with:
pos2 = ((curpos + 2) - getBit(key,curpos)) % 8;