I am currently trying to make an implementation of the encryption scheme DES but I've run into a problem early on. This is the first time I have ever performed bitwise manipulations in a program and I am not very proficient with C either. I apply a permutation and its inverse and the result is not the same as the input.
What I am trying to do is to apply the initial permutation and inverse permutation on a block of 64 bits. I have my block of 64 bits that I want to encrypt in the array input. According to the permutation table IP I take the first bit in the first byte and put it as bit 58 in the permutation. Bit 2 is sent to bit 50 and so on. After the permutation the result is divided in half and the sides swapped. This will enable it to be put back using the same algorithm but with the IPinverse table.
include <stdio.h>
include <stdlib.h>
static unsigned char Positions[8] = {1,2,4,8,16,32,64,128};
int main()
{
unsigned char input[8] = {'a','b','c','d','e','f','g','h'};
unsigned char permutation[8];
unsigned char inverse[8];
int i;
for (i = 0; i < 8; i++) {
permutation[i] = 0;
inverse[i] = 0;
}
int IP[8][8] ={{58,50,42,34,26,18,10,2},
{60,52,44,36,28,20,12,4},
{62,54,46,38,30,22,14,6},
{64,56,48,40,32,24,16,8},
{57,49,41,33,25,17, 9, 1},
{59,51,43,35,27,19,11,3},
{61,53,45,37,29,21,13,5},
{63,55,47,39,31,23,15,7}};
int IPinverse[8][8] ={{40,8,48,16,56,24,64,32},
{39,7,47,15,55,23,63,31},
{38,6,46,14,54,22,62,30},
{37,5,45,13,53,21,61,29},
{36,4,44,12,52,20,60,28},
{35,3,43,11,51,19,59,27},
{34,2,42,10,50,18,58,26},
{33, 1,41, 9,49,17,57,25}};
printf("\n Before: \n");
for (i = 0; i < 8; i++) {
printf(" %c", input[i]);
}
// Initial permutation
int bit, newpos;
unsigned char desiredbit;
for (bit = 0; bit < 64; bit++) {
// Get the location for where the bit will be sent and translate it to array index
newpos = ((int)IP[bit/8][bit%8])-1;
// examine the bit we're currently considering
desiredbit = input[bit/8] & Positions[bit%8];
// if equal to zero that means no change necessary
if (desiredbit != 0) {
// else it was a 1 and we need to set the appropriate bit to 1
desiredbit = Positions[newpos%8];
permutation[newpos/8] = desiredbit ^ permutation[newpos/8];
}
}
printf("\n Permutation: \n");
for (i = 0; i < 8; i++) {
printf(" %c", permutation[i]);
}
// Perform swap
unsigned char tempcopy[4] = {0,0,0,0};
int j;
for (j = 0; j < 4; j++) {
tempcopy[j] = permutation[j+4];
}
for (j = 0; j < 4; j++) {
permutation[j+4] = permutation[j];
permutation[j] = tempcopy[j];
}
// Reverse Permutation, remember to swap left side with right
for (bit = 0; bit < 64; bit++) {
newpos = ((int)IPinverse[bit/8][bit%8])-1;
desiredbit = permutation[bit/8] & Positions[bit%8];
if (desiredbit != 0) {
desiredbit = Positions[newpos%8];
inverse[newpos/8] = desiredbit ^ inverse[newpos/8];
}
}
printf("\n Reverse Permutation: \n");
for (i = 0; i < 8; i++) {
printf(" %c", inverse[i]);
}
return 0;
}
Your permutation contains indexes from 1 to 64, but the way you use them, they should be 0 to 63.
What's the swap for? If you permute, swap, then permute back, you won't reach the same place.
You need to verify that the permutation and reverse are indeed opposites. I'm surely not going to go over all the numbers and verify it.
Related
Taking a sequence of (non-empty) integers the program should first request the number of integers to read and dynamically allocate an array large enough to hold the number of values you read. You should then loop in the elements of the array. Then, your program must use malloc() to dynamically allocate two arrays, one to hold all the even numbers in the array you just read, and one to hold the odd numbers in the array. You must allocate just enough space for each array to hold odd and even numbers.
That is my test case
Please enter the number of times you want to enter the temperature:
4
Please enter the numbers:
21
40
31
50
odds are: 21
odds are: 0
evens are: 0
evens are: 40
This is my code:
#include <stdio.h>
#include<stdlib.h> // for malloc
int main(void) {
int counts = 0; // set a variable named counts recored how many of the times
printf("Please enter the number of times you want to enter the temperature: \n");
scanf("%d",&counts);
int *odd_evens;
odd_evens = malloc(sizeof(int)*(counts));
printf("Please enter the numberss: \n");
for (int i = 0; i < counts; i++) { // use for loop to read temperature
scanf("%d",&odd_evens[i]); // record the temperature
}
int odds_number = 0; // calcuate how many numbers are odds
int evens_number = 0; // calcuate how many numbers are evens
for (int i = 0; i < counts; i++) {
if (odd_evens[i] %2 == 0) {
odds_number++; // odds add one
}
else if (odd_evens[i] %2 != 0) {
evens_number++; // evens add one
}
}
int *odds;
odds = malloc(sizeof(int)*(odds_number)); // create dunamic array for odds
int *evens;
evens = malloc(sizeof(int)*(evens_number)); // create dunamic array for evens
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
for(int m = 0; m < odds_number; m++) {
printf("odds are: %d\n",odds[m]);
}
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
free(odd_evens);
free(odds);
free(evens);
return 0;
}
In my limited coding experience, this usually happens with invalid subscripts, but in my test code, the odd numbers are of length 2 and the even numbers are of length 2. The array range should be correct. Why does this happen?
One major problem is this loop:
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
Here you will go out of bounds of both evens and odds (leading to undefined behavior) since you use the index for odd_evens which most likely will be larger (unless all input is only odd, or only even).
You need to keep separate indexes for evens and odds:
unsigned evens_index = 0;
unsigned odds_index = 0;
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[evens_index++] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[odds_index++] = odd_evens[j];
}
}
Another problem is the printing of the even numbers:
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
Here you use the odds_number size instead of evens_number.
Background on what the code is supposed to do, vs what I am achieving.
So the dec2bin function is supposed to get the values/numbers decimal from the array dec_nums[]={0, 1, 77, 159, 65530, 987654321};
the function is supposed to convert the value to binary numbers and print it out.
the conversion is done correctly however, it prints the binary backward.
Can someone help me on figuring out what the problem is, or if there is another way to achieve the correct results?
int main() {
int dec_nums[] = {0, 1, 77, 159, 65530, 987654321};
int i;
printf("=== dec2bin ===\n");
for (i = 0; i < sizeof(dec_nums) / sizeof(int); i++)
dec2bin(dec_nums[i]);
return 0;
}
void dec2bin(int num) {
int saveNum = num;
if (saveNum == 0) {
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
} else {
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++) {
number = num % 2;
num = num / 2;
printf("%i", number);
}
printf("\n");
}
}
For bit fiddling unsigned types are preferrable, you avoid any kinds of problems with undefined behaviour due to under-/overflow.
Apart from, you can operate on bit masks:
for(unsigned mask = 1u << sizeof(mask) * CHAR_BIT - 1; mask; mask >>= 1)
{
unsigned bit = (value & mask) != 0;
// print it
}
CHAR_BIT is the value of bits within a char and comes from header limits.h, typically (but not necessarily) it is 8, with typically four bytes for ints you initialise the mask to 1 << 31 and further on shift it downwards until it reaches 1 << 0, i. e. 1, which is the last value yet considered. Yet another shift moves the single bit set out of the mask, so you get 0 and the loop aborts.
Above code will print leading zeros, you might prepend another loop that simply shifts down until the first 1-bit is met if you want to skip them.
This variant starts at most significant bit; by % 2 you always get the least significant bit instead – which is why you got the inverse order.
Side note: Getting length of an array is better done as sizeof(array)/sizeof(*array) – this avoids errors if you need to change the underlying type of the array...
A simple solution would be to write to bits into a char array, starting from the end of the array, the same way that we would do by hand.
Your dec2bin function would become (only minimal changes, with comments for added or changed lines):
void dec2bin(int num)
{
// declare a char array of size number_of_bits_in_an_int + 1 for the terminating null
char bin[sizeof(int) * CHAR_BIT + 1];
char* ix = bin + sizeof(bin) - 1; // make ix point to the last char
*ix-- = '\0'; // and write the terminating null
int saveNum = num;
if (saveNum == 0)
{
printf("\nBinary Number of %d", saveNum);
printf(" = 0");
}
else
{
int number;
int i;
printf("\nBinary Number of %i", saveNum);
printf(" = ");
for (i = 0; num > 0; i++)
{
number = num % 2;
num = num / 2;
*ix-- = '0' + number; // just write the bit representatin
}
printf("%s\n", ix+1); //print the binary representation
}
}
That is enough to get the expected result.
My objective for this program is to let the user determine the size of the array and dynamically allocate memory for whatever size they choose. Once the user defines the size of the array, random numbers that do no exceed the size of the array are placed into all of the allotted positions. Where I am having issues is removing duplicates from the array and replacing them with a value that is not being used,
Example:
Please enter the size of the array:
User Input: 5
Output of code: 5, 3, 3, 1, 2
I would need it to be something like this:
Please enter the size of the array:
User Input: 3
Output of program: 3, 1, 2
Currently reading "C Programming - A Modern Approach" by K.N. King (Second Edition).
if someone could point me in the right direction on how to approach this, it would be much appreciated.Here is my code thus far.
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
int main() {
int *UserData;
int TempPost;
int replace;
int UserInput;
int i;
int result;
bool digit_seen[UserInput];
int digit;
srand ((unsigned) time(NULL));
printf("Please enter the size of the array using a whole number: \n");
scanf("%d", &UserInput);
UserData = malloc(sizeof(int) * (UserInput ) +1);
for(i=0; i < UserInput; i ++) {
result = (( rand() % UserInput) + 1);
}
// check for duplicate values while putting values in array
while(UserInput>0){
digit = UserInput % UserInput;
if(digit_seen[digit])
break;
digit_seen[digit] = true;
UserInput /= UserInput;
if(UserInput > 0)
printf("Repeated digit \n");
else
printf("No repeated digit \n");
}
// Sorting the array using a Bubble sort
while(1){
replace = 0;
for (i=0; i<(UserInput - 1); i++){
if(UserData[i]>UserData[i+1]){
TempPost = UserData[i];
UserData[i] = UserData[i+1];
UserData[i+1] = TempPost;
replace = 1;
}
}
if(replace==0){
break;
}
}
printf("%d \n", result);
return 0;
}
It's not the most efficient way, but you can do it as you're generating the random numbers. When you pick a random number, go through all the previous elements of the array and see if it's already been used. Keep looping until you pick an unused number.
for (i = 0; i < UserInput; i++) {
do {
result = ( rand() % UserInput) + 1;
} while (in_array(result, UserData, i-1));
UserData[i] = result;
}
int in_array(int val, int* array, int array_size) {
for (int i = 0; i < array_size; i++) {
if (array[i] == val) {
return 1;
}
}
return 0;
}
A slightly more efficient way to do it is to initialize the array to 0. Then instead of picking random numbers, pick a random index to fill in, and repeat this until you pick an index that contains 0.
UserData = calloc(UserInput, sizeof(int));
for (i = 1; i <= UserInput; i++) {
int index;
do {
index = rand() % UserInput;
} while (UserData[index] != 0)
UserData[index] = i;
}
What you can do is shuffle the array instead. Just fill the array with all the numbers in order using a simple for loop, then shuffle it with something like this:
//read user input
//create array and fill with all the numbers in order
//[0,1,2,3,4,5 .. ... ]
int index, temp;
// size is the size of the array
for(int i = 0; i < size; i++)
{
index = rand()%size;//random place to pick from
temp = array[i];
array[i] = array[index];
array[index] = temp;
}
This is a lot more effecient -and less error prone- than your current approach.
I'm trying to solve one problem, which I found on website https://open.kattis.com/problems/coast. Tl;dr version of problem is, that for given map of landscape, I should print out length of coastline (without inner islands).
I receive 0/26 mark, but I have no idea why, I've tested, and as far as i checked, it worked. I assume it doesn't compile, but if that is the case, why is that? It compiles for me perfectly fine.
#include <stdio.h>
int edgeCount(int, int, char*);
int topToBottomCount(int, int, char*);
int leftToRightCount(int, int, char*);
int removingInsides(int, int, char*);
int main()
{
int n = 0; // number of strings
int m = 0; // strings lenghts
//printf("Enter N(number of strings) x M(strings lenght): ");
scanf("%d", &n);
scanf("%d", &m);
char coast[1024];
for(int i = 0; i < n; i++){
scanf("%s", coast+i*m); // adding strings to char coast[1024], making array of ones and zeroes // e.g we are adding 3x4 strings - 111100001111
} // it can also be looked as 1111
// 0000 - matrix
int coasts = edgeCount(n, m, coast); // 1111
coasts += topToBottomCount(n, m, coast);
coasts += leftToRightCount(n, m, coast);
coasts -= removingInsides(n, m, coast);
printf("%d - coasts\n", coasts);
return 0;
}
int edgeCount(int n, int m, char *coast){ // if 1 is placed at the edge of the "map", it is 1 coast (2 if it is at corner)
int edgeCoast = 0;
for(int i = 0; i < m; i++){ // top edges
if(coast[i] == '1')
edgeCoast++;
}
for(int i = m*n - m; i < m*n; i++){ // bottom edges (m*n - m = first char in the last string, it can be also looked as the last row in matrix)
if(coast[i] == '1')
edgeCoast++;
}
for(int i = 0; i <m*n; i+=m){ // left side edges (first column in matrix)
if(coast[i] == '1')
edgeCoast++;
}
for(int i = m-1; i < m*n; i+=m){ // right side edges (last column in matrix)
if(coast[i] == '1')
edgeCoast++;
}
return edgeCoast;
}
int topToBottomCount(int n, int m, char *coast){
int coasts = 0;
for(int i = 0; i < m*n - m; i++){ // we start from first char in "matrix", and move to the (m*n - m = 2nd last "row")
if(coast[i] ^ coast[i+m]) // we are checking if zero is placed above one or via versa
coasts++;
}
return coasts;
}
int leftToRightCount(int n, int m, char* coast){
int coasts = 0;
int p = m-1;
for(int i = 0; i < n*m; i++){ // we start from the first charr, and we are going trough whole matrix, but the last column
if(i == p){ // p = m - 1 (last char in first row)
p+=m; // p+=m (last char in next column, and so on)
continue; // we move to next iteration
}
if(i == m*n - 1) //if we are at last char in matrix, we break out from loop
break;
if(coast[i] ^ coast[i+1])
coasts++;
}
return coasts;
}
int removingInsides(int n, int m, char* coast){ // Lakes and islands in lakes are not contributing to the sea coast. we are checking if they exist.
int innerCoasts = 0;
for(int i = m + 1; i < n*m - m - 1; i ++){
if( coast[i] == '0' && coast[i] ^ coast[i-1] && coast[i] ^ coast[i+1] && coast[i] ^ coast[i-m] && coast[i] ^ coast[i+m]) // char has to be 0, and to hist left, right, above and under there has to be 1
innerCoasts++;
}
return innerCoasts * 4; // *4 because we added 4 coasts before for each island.
}
I tried compiling your code using the GCC C++ compiler (4.9.2). It compiled fine and I tested it using the sample problem in the link you provided. It spit out the right answer.
However, when I tried compiling using the GCC C compiler (also v 4.9.2), it fails with 'for' loop initial declarations are only allowed in C99 or C11 mode, which is explained by this SO question. I think your assignment was graded using a C compiler and the compilation of your program failed due to this error.
I have been working on an algorithm to find all permutations of the elements of a char array for a few days now and well it just doesn't seem to work.
The char array is an **array, which I iterate through based on the number entered by the user and I then malloc space for each word(40 chars each). The number entered by the user is the length of the array, and it is the number they expect to enter. This part works as expected.
What I am having trouble with is iterating through the char array and calculating the permutation of the entire set(**array). I then want to have another char array consisting of all permutations of the set. Now just permutations of the unit indices's of **array, not each indices's individual characters.
Does anybody have any tips on how to successfully do this, regardless of the size of the initial set? I assume it would be much easier if the set size where static.
My starting array looks like this as an example
char *array[] = {
"Hello",
"Calculator",
"Pencil",
"School Bus"
};
Which would be held in **array, with "Hello" in array[0] and "School Bus" in array[3], with '\0' at the end of each.
I want the permutation to be on the indices, not the characters.
So
"Hello"
.
.
.
"School BusSchool BusSchool BusSchool Bus"
Here's a dumb permutation generator (up to N=32... or 64).
#include <stdio.h>
const int N = 5;
int x[N];
int main( void ) {
int i,j;
x[0]=-1;
unsigned mask = -1; // unused numbers
for( i=0;; ) {
for( j=x[i]+1; j<N; j++ ) { // check remaining numbers
if( (mask>>j)&1 ) { // bit j is 1 -> not used yet
x[i] = j; // store the number
mask ^= (1<<x[i]); // mask used
// try going further, or print the permutation
if( ++i>=N ) { for( j=0; j<N; j++ ) printf( "%3i", x[j] ); printf( "\n" ); }
else x[i]=-1; // start next cell from 0
break;
}
}
// go back if there's no more numbers or cells
if( (j>=N) || (i>=N) ) {
if( --i<0 ) break;
mask ^= (1<<x[i]);
}
}
}
By your edit, I am taking that you have an array of four elements. Your desired output is a combination of these elements and is the concatenation of between one and four elements. The output may contain an input element more than once. Is this a correct summary?
If so, think of your output in four cases: for output generated from one, two, three, or four elements. For output generated from n elements, you have n^n possibilities. For all four of these cases combined, this gives you 1^1 + 2^2 + 3^3 + 4^4 = 288 possible outputs.
Your 1-element output permutations are simply: 0, 1, 2, 3
Your 2-element output permutations can be generated by the pseudo-code:
for i = 0 to 3 {
for j = 0 to 3 {
next_permutation = {i, j}
}
}
For 3- and 4-element output, permutations can be generated using three and four nested loops, respectively. For some arbitrary number of input elements x, you can generate permutations using the same technique with x number of nested loops. Be warned that the number of loops requires grows exponentially with the number of input elements, so this can get ugly fairly fast.
You can use the numbers from these permutations as indices into your initial array in order to generate the output as strings (as in your sample).
Update: Here's a recursive pseudo-code function that can generate these pseudo-permutations:
int output_array[dimension] = {0};
generate_combinations (unsigned dimension, int index) {
for i = 0 to (dimension-1) {
output_array[index] = i;
if index == 0
next_permutation = output_array
else
generate_combinations(dimension, index-1)
endif
}
}
You would use this with dimension set to the number of elements in your input array and index = dimension - 1. Hopefully, your input dimensionality won't be so large that this will recurse too deeply for your CPU to handle.
Here's one solution. Remember that the time complexity is factorial, and that if you're storing all the permutations then the space required is also factorial. You're not going to be able to do very many strings.
void CalculatePermutations(unsigned long permSize, const char** candidates, const char** currentPerm, unsigned long currentPermIdx, const char** ouputBuffer, unsigned long* nextOutputIdx)
{
//base case (found a single permutation)
if(currentPermIdx >= permSize){
unsigned long i = 0;
for(i = 0; i < permSize; ++i){
ouputBuffer[*nextOutputIdx] = currentPerm[i];
(*nextOutputIdx)++;
}
return;
}
//recursive case
unsigned long i = 0;
for(i = 0; i < permSize; ++i){
if(candidates[i]){
currentPerm[currentPermIdx] = candidates[i]; //choose this candidate
candidates[i] = NULL; //mark as no longer a candidate
CalculatePermutations(permSize, candidates, currentPerm, currentPermIdx + 1, ouputBuffer, nextOutputIdx);
candidates[i] = currentPerm[currentPermIdx]; //restore this as a possible candidate
}
}
}
int main(int argc, char** argv)
{
const char* allStrings[8] = {"0", "1", "2", "3", "4", "5", "6", "7"};
static const char* allPermutations[322560]; // = fact(8) * 8
const char* permBuffer[8];
unsigned long nextOutputIdx = 0;
CalculatePermutations(8, allStrings, permBuffer, 0, allPermutations, &nextOutputIdx);
for(unsigned long i = 0; i < 322560; ++i){
printf("%s", allPermutations[i]);
if(i % 8 == 7){
printf("\n");
} else {
printf(", ");
}
}
return 0;
}
here my code that give us the r-permutation of a n! possible permutations. Code works with all kind of size (I only check with 3!, 4!, 5! and 8! and always works correct, so I suppouse that works right):
#include <stdio.h>
#include <stdint.h>
enum { NPER = 4, };
static const char *DukeQuote[NPER] = {
"Shake it, baby!",
"You wanna dance?",
"Suck it down!",
"Let's rock!",
};
void fill(const uint32_t, uint32_t * const);
void fact(const uint32_t, uint32_t * const);
void perm(uint32_t, const uint32_t, const uint32_t * const, uint32_t * const);
int main(void)
{
uint32_t f[NPER+1];
uint32_t p[NPER];
uint32_t r, s;
/* Generate look-up table for NPER! factorial */
fact(NPER, f);
/* Show all string permutations */
for(r = 0; r < f[NPER]; r++)
{
perm(r, NPER, f, p);
for(s = 0; s < NPER; s++)
printf("%s, ", DukeQuote[p[s]]);
printf("\n");
}
return 0;
}
/* Generate look-up table for n! factorial.
That's a trick to improve execution */
void fact(const uint32_t n, uint32_t * const f)
{
uint32_t k;
for(f[0] = 1, k = 1; k <= n; k++)
f[k] = f[k-1] * k;
}
/* Fill the vector starting to 0 up to n-1 */
void fill(const uint32_t n, uint32_t * const p)
{
uint32_t i;
for(i = 0; i < n; i++)
p[i] = i;
}
/* Give us the r-permutation of n! possible permutations.
r-permutation will be inside p vector */
void perm(uint32_t r, const uint32_t n, const uint32_t * const f, uint32_t * const p)
{
uint32_t i, j;
fill(n, p);
for(i = n-1; i > 0; i--)
{
uint32_t s;
j = r / f[i];
r %= f[i];
s = p[j];
for(; j < i; j++)
p[j] = p[j+1];
p[i] = s;
}
}
For instance, if you want the first permutation of 4! possibles then:
perm(0, 4, f, p)
where p will have:
p = [3, 2, 1, 0]
Take care, 0 is 1th, 1 is 2th, and so on.
You can use p[i] like indices in your string array, how I've used in DukeQuote array.
PD1: This code implements the correct definition of a permutation (A r-permutation is a bijection. The cardinal of the set of all bijections N_n to N_n is exactly n!)
PD2: I hope that my mistakes in my poor English doesn't influence in the goal of my explanation.