## Instructions

### Objective

Write a program to rearrange the order of bits in C language.

## Requirements and Specifications

**Objective**

Practice in bit manipulation of integers in the C programming language.

**Submitting Your Work**

Complete your C assignment program file as bits.c and submit it and your report via the Lab Exercise 3 Submission item on the course web site. You must submit your program by 11:59 PM two days after your scheduled lab session.

**Introduction**

Your task for this lab exercise is to complete several function definitions which solve puzzles, using only a limited set of operators in the C language. In addition, you must write a main() function which calls each of your solution functions to demonstrate that each function performs as specified.

**Screenshots of output**

**Source Code**

```
#include
/* Function prototypes */
int func1(int x, int y);
int func2(int x, int y);
int func3(int x);
int func4(int x);
int func5(int highbit, int lowbit);
int func6(int x, int m, int n);
int main()
{
printf("Testing func1 function:\n");
printf("func1(5,6) = 0x%X, (expected = 0x%X)\n", func1(5,6), 5 & 6);
printf("func1(0xFF,0x1234) = 0x%X, (expected = 0x%X)\n", func1(0xFF, 0x1234), 0xFF & 0x1234);
printf("\nTesting func2 function:\n");
printf("func2(4,5) = 0x%X, (expected = 0x%X)\n", func2(4,5), 4 ^ 5);
printf("func2(5,6) = 0x%X, (expected = 0x%X)\n", func2(5,6), 5 ^ 6);
printf("func2(0xFF,0x1234) = 0x%X, (expected = 0x%X)\n", func2(0xFF, 0x1234), 0xFF ^ 0x1234);
printf("\nTesting func3 function:\n");
printf("func3(5) = 0x%X, (expected = 0x%X)\n", func3(5), 0);
printf("func3(7) = 0x%X, (expected = 0x%X)\n", func3(7), 1);
printf("func3(0x100) = 0x%X, (expected = 0x%X)\n", func3(0x100), 0);
printf("func3(0x255) = 0x%X, (expected = 0x%X)\n", func3(0x255), 1);
printf("\nTesting func4 function:\n");
printf("func4(0xFFFFFFFD) = 0x%X, (expected = 0x%X)\n", func4(0xFFFFFFFD), 0);
printf("func4(0xAAAAAAAA) = 0x%X, (expected = 0x%X)\n", func4(0xAAAAAAAA), 1);
printf("func4(0xABEABEAB) = 0x%X, (expected = 0x%X)\n", func4(0xABEABEAB), 1);
printf("func4(0xFFFF) = 0x%X, (expected = 0x%X)\n", func4(0xFFFF), 0);
printf("\nTesting func5 function:\n");
printf("func5(5,3) = 0x%X, (expected = 0x%X)\n", func5(5,3), 0x38);
printf("func5(31,16) = 0x%X, (expected = 0x%X)\n", func5(31,16), 0xFFFF0000);
printf("func5(1,2) = 0x%X, (expected = 0x%X)\n", func5(1,2), 0);
printf("\nTesting func6 function:\n");
printf("func6(0x12345678,1,3) = 0x%X, (expected = 0x%X)\n", func6(0x12345678,1,3), 0x56341278);
printf("func6(0xDEADBEEF,0,2) = 0x%X, (expected = 0x%X)\n", func6(0xDEADBEEF,0,2), 0xDEEFBEAD);
printf("\n");
return 0;
}
/*
* func1 returns x & y
*/
int func1(int x, int y)
{
/* We use the DeMorgan's theorem to remove the and: x*y = ~(~x + ~y) */
return ~((~x) | (~y));
}
/*
* func2 returns x ^ y
*/
int func2(int x, int y)
{
/* We use the boolean expression for xor = ~x*y + x*~y and we remove the or using
the DeMorgan's theorem x+y = ~(~x*~y) */
return ~(~(~x & y) & ~(x & ~y));
}
/*
* func3 returns 1 if an odd numbered bit in x is 1
*/
int func3(int x)
{
/* Tests the odd bits in each of the 4 bytes of the 32bit int, test the result
logically using double ! (any non zero becomes 1) then ors all of the results
if any is 1 returns 1 */
int b1 = !!(x & 0xAA); /* test bits in lowest byte */
int b2 = !!((x >> 8) & 0xAA); /* test bits in second byte */
int b3 = !!((x >> 16) & 0xAA); /* test bits in third byte */
int b4 = !!((x >> 24) & 0xAA); /* test bits in highest byte */
return b1 | b2 | b3 | b4; /* if any byte has an odd 1, return 1 */
}
/*
* func4 returns 1 if all the odd numbered bits in x is 1
*/
int func4(int x)
{
/* Tests the odd bits in each of the 4 bytes of the 32bit int, then ands all of them
if all bits are set the result must be 0xAA so it's xored with 0xAA and if zero
returns 1 by making a logical inversion with !
*/
int b1 = (x & 0xAA); /* test bits in lowest byte */
int b2 = ((x >> 8) & 0xAA); /* test bits in second byte */
int b3 = ((x >> 16) & 0xAA); /* test bits in third byte */
int b4 = ((x >> 24) & 0xAA); /* test bits in highest byte */
return !((b1 & b2 & b3 & b4) ^ 0xAA); /* if all bytes have odd ones, return 1 */
}
/*
* func5 returns a mask with ones between highbit and lowbit
*/
int func5(int highbit, int lowbit)
{
/* Makes a bitmask from the high bit down, then makes a mask from the low bit up
and returns the and of both */
int maskhi = ((1 << highbit) + (~0)) | (1 << highbit); /* mask up to high bit */
int masklow = (~0) << lowbit; /* mask up to lowbit */
return maskhi & masklow; /* make mask combining both */
}
/* Swaps the mth byte and the nth byte of an integer */
int func6(int x, int m, int n)
{
/* saves the initial bytes shifting them and masking them, then
clears the old positions and ors the swapped values */
int byte1 = (x >> (m << 3)) & 0xFF; /* move byte at position m*8 down, mask 8 bits */
int byte2 = (x >> (n << 3)) & 0xFF;/* move byte at position n*8 down, mask 8 bits */
int mask1 = ~(0xFF << (m << 3)); /* move 0xFF up at position m*8, invert to get zeros there */
int mask2 = ~(0xFF << (n << 3)); /* move 0xFF up at position n*8, invert to get zeros there */
x = (x & mask1) | (byte2 << (m<<3)); /* replace first value */
x = (x & mask2) | (byte1 << (n<<3)); /* replace second value */
return x;
}
```

**DECRYPT PROGRAM**

```
#include
/*
* Function prototypes
*/
void get_keys (char *twokeys, unsigned *key1, unsigned *key2);
unsigned int get_n_bits (unsigned bits, int width, int index);
unsigned int rotate_left3(unsigned bits);
void shuffle_nibbles (unsigned *bits);
void decode_28bits (unsigned cipher, char *plain, unsigned key1, unsigned key2);
/*
* Main function
*/
int main(int argc, char **argv)
{
char line[10], plaintext[10];
unsigned int bits;
unsigned key1, key2;
if (argc != 2) /* if there was no command line argument */
{
printf("Missing key argument!\n");
printf("Usage:\n %s key\n", argv[0]);
return 0;
}
get_keys (argv[1], &key1, &key2); /* get the 2 keys from the cmd line argument */
/* Get the next 7 characters of input (leaving space for the null at the end) */
while (fgets(line, 8, stdin) != NULL)
{
if (line[0] != '\n') /* ignore empty lines */
{
/* convert to a number */
if (sscanf(line, "%x", &bits) == 1) /* read hexadecimal ciphertext */
{
decode_28bits (bits, plaintext, key1, key2); /* decode using keys */
printf("%s", plaintext); /* print result */
}
}
else
printf("\n");
}
printf("\n");
return 0;
}
/*
* Extracts two 28=bit keys from 4 bytes
*/
void get_keys (char *twokeys, unsigned *key1, unsigned *key2)
{
int i;
*key1 = 0; /* initialize keys to zero */
*key2 = 0;
for (i = 0; i < 4; i++) /* for the 4 characters used in each key */
{
*key1 = (*key1 << 7) | (twokeys[i] & 0x7F); /* add 7 bits of each character of first key */
*key2 = (*key2 << 7) | (twokeys[i + 4] & 0x7F); /* add 7 bits of each character of second key */
}
}
/*
* Returns the integer value of a specified subsequence of 32 bits,
* width is the number of bits to be extracted, index*width is the index
* of the rightmost bit to extract
*/
unsigned int get_n_bits (unsigned bits, int width, int index)
{
return (bits >> (index * width)) & ((1 << width) - 1); /* shift to put selected bits at lowest position, mask using width */
}
/*
* Given a sequence of 7 bits, rotate 3 bits to the left
*/
unsigned int rotate_left3(unsigned bits)
{
int i, msb;
for (i = 0; i < 3; i++)
{
msb = (bits >> 6) & 1; /* get msb bit */
bits = (bits << 1) | msb; /* shift and put msb at lsb to rotate */
}
return bits & 0x7F; /* mask to leave only 7 bits */
}
/* shuffle nibbles in the 28 bit value given as argument, the shuffle inverts:
3 1 2 0 4 5 6 -> 6 5 4 3 2 1 0
*/
void shuffle_nibbles (unsigned *bits)
{
int shuffled = 0;
shuffled |= get_n_bits(*bits, 4, 0); /* locate nibble 6 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 1); /* locate nibble 5 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 2); /* locate nibble 4 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 6); /* locate nibble 3 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 4); /* locate nibble 2 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 5); /* locate nibble 1 */
shuffled <<= 4; /* shift left up 4 bits */
shuffled |= get_n_bits(*bits, 4, 3); /* locate nibble 0 */
*bits = shuffled; /* update bits with shuffled value */
}
/*
* Decode a block of 28 bits
*/
void decode_28bits (unsigned cipher, char *plain, unsigned key1, unsigned key2)
{
int i;
cipher = cipher ^ key2; /* xor ciphertext with key2 */
shuffle_nibbles(&cipher); /* shuffle nibbles */
cipher = cipher ^ key1; /* xor ciphertext with key1 */
for (i = 0; i < 4; i++) /* process 4 septets */
{
plain[3- i] = rotate_left3(get_n_bits(cipher, 7, i)); /* get septet and rotate, save as 8 bit char */
}
plain[4] = 0; /* insert end of string */
}
```

## Similar Samples

Explore our diverse collection of programming assignment samples at ProgrammingHomeworkHelp.com. Our samples showcase expertise in Java, Python, C++, and more, demonstrating thorough problem-solving skills and clear, structured coding techniques. See how our solutions can assist you in mastering programming concepts and achieving academic success.

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C

C