Thread: Need help with phantoms and function(affine)

  1. #1
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39

    Need help with phantoms and function(affine)

    I have this program that is not working properly. Basically, it is supposued to take a file called input.txt which has a single sentence in it and encrypt it to the output file called output.txt. The first issue is with the selection of number 1 in the menu. It asks for the input file name and I type it in, then it asks for the cipher keys. However it also is supposed to ask for the output file name and is not. So I placed fflush(stdin); after the scanf() to flush the buffer. Without it, I never get to enter the cipher keys which are 19,4. Why is it not asking for the output file name after the input file name?
    Also the function affine does not appear to be used anywhere or am I wrong?
    Any suggestions? I am sure I am overlooking something small.

    Code:
    #pragma warning ( disable: 4996)
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    
    
    #define bool int
    
    
    int menu(); // Prints the menu
    int euclid(int, int); // Performs the extended euclid's algorithm
    void doaffine(char[],char[], int, int); // encrypts a file using the given keys
    void affine(int, int, FILE*, FILE*); // helps the function doaffine
    bool get_decrypt(int a, int b, int& c, int& d); // computes decryption keys c
    
    
    // and d from given a and b.
    
    
    int main() {
    
    
    	// Main menu of driver program
    	int ans = menu();
    	while (ans != 4) {
    
    
    		// Allows user to test encryption function
    		if (ans == 1) {
    
    
    			// Get pertinent info from the user.
    			char inputfile[100];
    			char outputfile[100];
    			printf( "Enter input file name.");
    			scanf("%c", &inputfile);
    			fflush(stdin);
    			printf( "Enter output file name.");
    			scanf("%c", &outputfile);
    			fflush(stdin);
    			int a,b;
    			printf("Enter Affine cipher values of a and b.");
    			scanf( " %d %d ", &a,&b);
    			fflush(stdin);
    			// Make the function call with this info.
    			doaffine(inputfile, outputfile, a, b);
    
    
    		}
    
    
    		// Allows user to test decryption key function
    		else if (ans == 2) {
    
    
    			// Gets necessary info from the user.
    			int a,b;
    			printf("Enter Affine cipher values of a and b.");
    			scanf( " %d %d ", &a,&b);
    			fflush(stdin);
    			// Calls the function and writes the output to the screen.
    			int c,d;
    			if (get_decrypt(a,b,c,d))
    				printf("Decrypting keys are %d and %d",&a,&b);
    			else
    				printf("Sorry, those are not valid keys.");
    
    
    		}
    		else if (ans == 3)
    			system("dir /p");
    		else if (ans > 4)
    			printf("Sorry, not a valid menu choice. Try again.");
    
    
    		ans = menu();
    	}
    
    
    }
    
    
    // Prints out user's choices.
    int menu() {
    	int pick;
    	printf("Pick your menu choice :\n\n");
    	printf("1. Apply affine cipher to a file\n");
    	printf("2. Find corresponding decrypting keys for the affine cipher\n");
    	printf("3. Get directory listing \n");
    	printf("4. Quit.\n");
    	scanf("%d",&pick);
    	return pick;
    }
    
    
    // Opens appropriate streams and calls affine to do actual encryption.
    void doaffine(char inputfile[], char outputfile[], int a, int b) {
    
    
    	// Checks to see if the key is valid.
    	if (euclid(a,26)<0)
    		printf("Sorry that is not a valid affine shift key.");
    	else {
    		
    		// Opens appropriate streams
    		//open input and out put files here
    		//////////
    	}
    
    
    }
    
    
    // This function does the actual translation.
    void affine(int a, int b, FILE *input, FILE *output) {
    
    
    	// Loop until everything from the input file has been read.
    
    
    	char c;
    	while (fscanf(input,"%c",&c)!=EOF) {
    
    
    
    
    	// Only encrypt if it's an upper or lowercase letter.
    	if (c >= 65 && c <= 90)
    		c = char( ( a*((int)c-65)+b) + 65);
    	else if (c >= 97 && c <= 122)
    		c = char ( ( a*((int)c-97)+b) + 97);
    
    
    		// Output the character to the output file.
    		fprintf(output,"%c",c);
    	}
    
    
    }
    
    
    // Determines decryption keys c and d for the given encryption keys a and b.
    bool get_decrypt(int a, int b, int& c, int& d) {
    
    
    	// Find the inverse of a mod 26, if it exists.
    	int inverse = euclid(a, 26);
    
    
    	// A negative value for inverse indicates no inverse, and an invalid key.
    	if (inverse < 0) {
    		c = 0;
    		d = 0;
    		return false;
    	}
    	else {
    		c = inverse; // From class.
    		d = (-1*b*c); // Look at math below to explain this.
    
    
    		// Accounts for the case where d ends up negative.
    		if (d < 0)
    			d += 26;
    	}
    	return true;
    }
    
    
    	/*
    	Derivation of above result:
    
    
    	e(x) = ax + b
    	d(x) = cx + d
    	= c(ax + b) + d
    	= cax + bc + d
    	= x, as required by all cryptosystems.
    
    
    	Equating coefficients, we have ca = 1, and (bc + d) = 0
    	This means that c = a^(-1) mod 26, and d = -bc mod 26.
    	*/
    
    
    
    
    	// Precondition: n > x, and n and x are positive integers,
    	// Post condition: Returns x' the inverse of x (mod n), if gcd(x,n)=1 else
    	// returns -1*gcd(x,n)
    int euclid(int x, int n) {
    	int t0=0, t1=1, t2;
    	int r0,r1,r2,q;
    
    
    	// Sets up the first three remainders and the quotient in Euclid's algorithm.
    	r0 = n;
    	r1 = x;
    	r2 = n%x;
    	q = n/x;
    
    
    	// Set's up doing the equation backwards for the inverse solution.
    	// The 100*26 is to ensure that t2 stays positive.
    	t2 = (t0 - q*t1 + 100*26) % 26;
    	if (r1 == 1)
    		t2 = 1;
    
    
    	// Stops when repeated division finally yields no remainder, as in Euclid's.
    	while (r2!=0) {
    
    
    		// Carries out division
    		int temp = r2;
    		q = r1/r2;
    		r2 = r1 - q*r2;
    		r1 = temp;
    
    
    		// Carries out next step working the equations "backwards"
    		if (r2!= 0) {
    			int temp2 = t2;
    			t2 = (t1 - q*t2 + 100*26) % 26;
    			t1 = temp2;
    		}
    	}
    
    
    	// Based on whether an inverse exists, either a positive value (the inverse)
    	// is returned or the -gcd(x,n) is returned.
    	if (r1 == 1)
    		return t2;
    	else
    		return -r1;
    }

  2. #2
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39
    Ok I found and fixed my input issue. I needed %s not %c. Now I need to fix the function(doaffine) under the ELSE:

    Code:
    #pragma warning ( disable: 4996)
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    
    
    #define bool int
    
    
    int menu(); // Prints the menu
    int euclid(int, int); // Performs the extended euclid's algorithm
    void doaffine(char[],char[], int, int); // encrypts a file using the given keys
    void affine(int, int, FILE*, FILE*); // helps the function doaffine
    bool get_decrypt(int a, int b, int& c, int& d); // computes decryption keys c
    
    
    // and d from given a and b.
    
    
    int main() {
    
    
        // Main menu of driver program
        int ans = menu();
        while (ans != 4) {
    
    
            // Allows user to test encryption function
            if (ans == 1) {
    
    
                // Get pertinent info from the user.
                char inputfile[100];
                char outputfile[100];
                printf( "Enter input file name.");
                scanf("%s", &inputfile);
    
                printf( "Enter output file name.");
                scanf("%s", &outputfile);
    
                int a,b;
                printf("Enter Affine cipher values of a and b.");
                scanf( " %d %d ", &a,&b);
    
                // Make the function call with this info.
                doaffine(inputfile, outputfile, a, b);
    
    
            }
    
    
            // Allows user to test decryption key function
            else if (ans == 2) {
    
    
                // Gets necessary info from the user.
                int a,b;
                printf("Enter Affine cipher values of a and b.");
                scanf( " %d %d ", &a,&b);
                fflush(stdin);
                // Calls the function and writes the output to the screen.
                int c,d;
                if (get_decrypt(a,b,c,d))
                    printf("Decrypting keys are %d and %d",&a,&b);
                else
                    printf("Sorry, those are not valid keys.");
    
    
            }
            else if (ans == 3)
                system("dir /p");
            else if (ans > 4)
                printf("Sorry, not a valid menu choice. Try again.");
    
    
            ans = menu();
        }
    
    
    }
    
    
    // Prints out user's choices.
    int menu() {
        int pick;
        printf("Pick your menu choice :\n\n");
        printf("1. Apply affine cipher to a file\n");
        printf("2. Find corresponding decrypting keys for the affine cipher\n");
        printf("3. Get directory listing \n");
        printf("4. Quit.\n");
        scanf("%d",&pick);
        return pick;
    }
    
    
    // Opens appropriate streams and calls affine to do actual encryption.
    void doaffine(char inputfile[], char outputfile[], int a, int b) {
    
    
        // Checks to see if the key is valid.
        if (euclid(a,26)<0)
            printf("Sorry that is not a valid affine shift key.");
        else {
    
            // Opens appropriate streams
            //open input and out put files here
            //////////
        }
    
    
    }
    
    
    // This function does the actual translation.
    void affine(int a, int b, FILE *input, FILE *output) {
    
    
        // Loop until everything from the input file has been read.
    
    
        char c;
        while (fscanf(input,"%c",&c)!=EOF) {
    
    
    
    
        // Only encrypt if it's an upper or lowercase letter.
        if (c >= 65 && c <= 90)
            c = char( ( a*((int)c-65)+b) + 65);
        else if (c >= 97 && c <= 122)
            c = char ( ( a*((int)c-97)+b) + 97);
    
    
            // Output the character to the output file.
            fprintf(output,"%c",c);
        }
    
    
    }
    
    
    // Determines decryption keys c and d for the given encryption keys a and b.
    bool get_decrypt(int a, int b, int& c, int& d) {
    
    
        // Find the inverse of a mod 26, if it exists.
        int inverse = euclid(a, 26);
    
    
        // A negative value for inverse indicates no inverse, and an invalid key.
        if (inverse < 0) {
            c = 0;
            d = 0;
            return false;
        }
        else {
            c = inverse; // From class.
            d = (-1*b*c); // Look at math below to explain this.
    
    
            // Accounts for the case where d ends up negative.
            if (d < 0)
                d += 26;
        }
        return true;
    }
    
    
        /*
        Derivation of above result:
    
    
        e(x) = ax + b
        d(x) = cx + d
        = c(ax + b) + d
        = cax + bc + d
        = x, as required by all cryptosystems.
    
    
        Equating coefficients, we have ca = 1, and (bc + d) = 0
        This means that c = a^(-1) mod 26, and d = -bc mod 26.
        */
    
    
    
    
        // Precondition: n > x, and n and x are positive integers,
        // Post condition: Returns x' the inverse of x (mod n), if gcd(x,n)=1 else
        // returns -1*gcd(x,n)
    int euclid(int x, int n) {
        int t0=0, t1=1, t2;
        int r0,r1,r2,q;
    
    
        // Sets up the first three remainders and the quotient in Euclid's algorithm.
        r0 = n;
        r1 = x;
        r2 = n%x;
        q = n/x;
    
    
        // Set's up doing the equation backwards for the inverse solution.
        // The 100*26 is to ensure that t2 stays positive.
        t2 = (t0 - q*t1 + 100*26) % 26;
        if (r1 == 1)
            t2 = 1;
    
    
        // Stops when repeated division finally yields no remainder, as in Euclid's.
        while (r2!=0) {
    
    
            // Carries out division
            int temp = r2;
            q = r1/r2;
            r2 = r1 - q*r2;
            r1 = temp;
    
    
            // Carries out next step working the equations "backwards"
            if (r2!= 0) {
                int temp2 = t2;
                t2 = (t1 - q*t2 + 100*26) % 26;
                t1 = temp2;
            }
        }
    
    
        // Based on whether an inverse exists, either a positive value (the inverse)
        // is returned or the -gcd(x,n) is returned.
        if (r1 == 1)
            return t2;
        else
            return -r1;
    }
    
    
    




  3. #3
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39
    This was originally written in C++, but I need to have it in C. This was the code that was under the ELSE in the doaffine() function:

    Code:
                else{
    		// Opens appropriate files
    		ifstream input(inputfile);
    		ofstream output(outputfile);
    
    
    
    
    		affine(a,b,input,output);
    
    
    		// Closes the filess
    		input.close();
    		output.close();
            }

  4. #4
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39
    I know this is NOT the full answer, but am I going in the correct direction?

    Code:
    void doaffine(char inputfile[], char outputfile[], int a, int b) {
    
    
    	// Checks to see if the key is valid.
    	if (euclid(a,26)<0)
    		printf("Sorry that is not a valid affine shift key.");
    	else {
    		
    		// Opens appropriate files
    	    input(inputfile) = fopen("inputFile.txt", "r");
    		output(outputfile) = fopen("output.txt", "w");
    
    
    
    
    		affine(a,b,input,output);
    
    
    		// Closes the filess
    		input.close();
    		output.close();
    	}
    
    
    }

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    In C, you open and close, and read and write, using the file pointer:
    Code:
    FILE *fpIn, *fpOut; //just common names, not required to be this same variable name/s
    
    fpIn=fopen(fileIn, "r");  //fileIn is the filename of the input file - a char array, probably
    fpOut=fopen(fileOut, "w");  //fileOut is the filename of the output file,    ditto
    
    if(!fpIn || !fpOut) {
        printf("Error opening file/s!\n");
        return 1; //or exit(1)? or EXIT_FAILURE??
    }
    //other code
    
    //more code
    
    //end of file reading and writing
    fclose(fpIn);
    fclose(fpOut);
    }
    fflush(stdin); doesn't usually work - and is not supported. fflush() works with OUTPUT streams, not input streams.

    Also, when you print out a or b, you should not include & - that is the "address of" operator, and would be used to print out the ADDRESS OF a or b, which is not what you want.

    You would use &a and &b, when you are changing their value - so scanf("%d",&a), would be correct, also &b, ditto.

    Also, please post your program code as PLAIN TEXT, so it is handled right by the forum software, and has the right color, line numbers, and font.
    Last edited by Adak; 12-06-2012 at 09:05 PM.

  6. #6
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39
    Quote Originally Posted by Adak View Post
    In C, you open and close, and read and write, using the file pointer:
    Code:
    FILE *fpIn, *fpOut; //just common names, not required to be this same variable name/s
    
    fpIn=fopen(fileIn, "r");  //fileIn is the filename of the input file - a char array, probably
    fpOut=fopen(fileOut, "w");  //fileOut is the filename of the output file,    ditto
    
    if(!fpIn || !fpOut) {
        printf("Error opening file/s!\n");
        return 1; //or exit(1)? or EXIT_FAILURE??
    }
    //other code
    
    //more code
    
    //end of file reading and writing
    fclose(fpIn);
    fclose(fpOut);
    }
    fflush(stdin); doesn't usually work - and is not supported. fflush() works with OUTPUT streams, not input streams.

    Also, when you print out a or b, you should not include & - that is the "address of" operator, and would be used to print out the ADDRESS OF a or b, which is not what you want.

    You would use &a and &b, when you are changing their value - so scanf("%d",&a), would be correct, also &b, ditto.

    Also, please post your program code as PLAIN TEXT, so it is handled right by the forum software, and has the right color, line numbers, and font.

    How do you post as plain text? I know...stupid question

  7. #7
    Registered User
    Join Date
    Oct 2012
    Location
    Forest Hill, Maryland, United States
    Posts
    39
    Well you can look at my code now, but I still have an issue where the console program stops after the input of my keys. I guess I still have an error somewhere.

    Code:
    #pragma warning ( disable: 4996)
    #include <stdlib.h>
    #include <time.h>
    #include <stdio.h>
    
    #define bool int
    
    int menu(); // Prints the menu
    int euclid(int, int); // Performs the extended euclid's algorithm
    void doaffine(char[],char[], int, int); // encrypts a file using the given keys
    void affine(int, int, FILE*, FILE*); // helps the function doaffine
    bool get_decrypt(int a, int b, int& c, int& d); // computes decryption keys c
    
    // and d from given a and b.
    
    int main() {
    
    	// Main menu of driver program
    	int ans = menu();
    	while (ans != 4) {
    
      // Allows user to test encryption function
      if (ans == 1) {
    
       // Get pertinent info from the user.
       char inputfile[100];
       char outputfile[100];
       printf( "Enter input file name.");
       scanf("%s", &inputfile);
       
       printf( "Enter output file name.");
       scanf("%s", &outputfile);
       
       int a,b;
       printf("Enter Affine cipher values of a and b.");
       scanf( " %d %d ", &a,&b);
       
       // Make the function call with this info.
       doaffine(inputfile, outputfile, a, b);
    
      }
    
      // Allows user to test decryption key function
      else if (ans == 2) {
    
       // Gets necessary info from the user.
       int a,b;
       printf("Enter Affine cipher values of a and b.");
       scanf( " %d %d ", &a,&b);
       fflush(stdin);
       // Calls the function and writes the output to the screen.
       int c,d;
       if (get_decrypt(a,b,c,d))
        printf("Decrypting keys are %d and %d",&a,&b);
       else
        printf("Sorry, those are not valid keys.");
    
      }
      else if (ans == 3)
       system("dir /p");
      else if (ans > 4)
       printf("Sorry, not a valid menu choice. Try again.");
    
      ans = menu();
    	}
    
    }
    
    // Prints out user's choices.
    int menu() {
    	int pick;
    	printf("Pick your menu choice :\n\n");
    	printf("1. Apply affine cipher to a file\n");
    	printf("2. Find corresponding decrypting keys for the affine cipher\n");
    	printf("3. Get directory listing \n");
    	printf("4. Quit.\n");
    	scanf("%d",&pick);
    	return pick;
    }
    
    // Opens appropriate streams and calls affine to do actual encryption.
    void doaffine(char inputfile[], char outputfile[], int a, int b) {
    
    	FILE *input, *output;
    
    	// Checks to see if the key is valid.
    	if (euclid(a,26)<0)
      printf("Sorry that is not a valid affine shift key.");
    	else {
      
      // Opens appropriate files
         input = fopen("input.txt", "r");
      output = fopen("output.txt", "w");
    
    
      affine(a,b,input,output);
    
      // Closes the filess
      fclose(input);
      fclose(output);
    	}
    
    }
    
    // This function does the actual translation.
    void affine(int a, int b, FILE *input, FILE *output) {
    
    	// Loop until everything from the input file has been read.
    
    	char c;
    	while (fscanf(input,"%c",&c)!=EOF) {
    
    
    	// Only encrypt if it's an upper or lowercase letter.
    	if (c >= 65 && c <= 90)
      c = char( ( a*((int)c-65)+b) + 65);
    	else if (c >= 97 && c <= 122)
      c = char ( ( a*((int)c-97)+b) + 97);
    
      // Output the character to the output file.
      fprintf(output,"%c",c);
    	}
    
    }
    
    // Determines decryption keys c and d for the given encryption keys a and b.
    bool get_decrypt(int a, int b, int& c, int& d) {
    
    	// Find the inverse of a mod 26, if it exists.
    	int inverse = euclid(a, 26);
    
    	// A negative value for inverse indicates no inverse, and an invalid key.
    	if (inverse < 0) {
      c = 0;
      d = 0;
      return false;
    	}
    	else {
      c = inverse; // From class.
      d = (-1*b*c); // Look at math below to explain this.
    
      // Accounts for the case where d ends up negative.
      if (d < 0)
       d += 26;
    	}
    	return true;
    }
    
    	/*
    	Derivation of above result:
    
    	e(x) = ax + b
    	d(x) = cx + d
    	= c(ax + b) + d
    	= cax + bc + d
    	= x, as required by all cryptosystems.
    
    	Equating coefficients, we have ca = 1, and (bc + d) = 0
    	This means that c = a^(-1) mod 26, and d = -bc mod 26.
    	*/
    
    
    	// Precondition: n > x, and n and x are positive integers,
    	// Post condition: Returns x' the inverse of x (mod n), if gcd(x,n)=1 else
    	// returns -1*gcd(x,n)
    int euclid(int x, int n) {
    	int t0=0, t1=1, t2;
    	int r0,r1,r2,q;
    
    	// Sets up the first three remainders and the quotient in Euclid's algorithm.
    	r0 = n;
    	r1 = x;
    	r2 = n%x;
    	q = n/x;
    
    	// Set's up doing the equation backwards for the inverse solution.
    	// The 100*26 is to ensure that t2 stays positive.
    	t2 = (t0 - q*t1 + 100*26) % 26;
    	if (r1 == 1)
      t2 = 1;
    
    	// Stops when repeated division finally yields no remainder, as in Euclid's.
    	while (r2!=0) {
    
      // Carries out division
      int temp = r2;
      q = r1/r2;
      r2 = r1 - q*r2;
      r1 = temp;
    
      // Carries out next step working the equations "backwards"
      if (r2!= 0) {
       int temp2 = t2;
       t2 = (t1 - q*t2 + 100*26) % 26;
       t1 = temp2;
      }
    	}
    
    	// Based on whether an inverse exists, either a positive value (the inverse)
    	// is returned or the -gcd(x,n) is returned.
    	if (r1 == 1)
      return t2;
    	else
      return -r1;
    }
    Need help with phantoms and function(affine)-screen-jpg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 09-07-2012, 04:35 AM
  2. Replies: 13
    Last Post: 03-20-2012, 08:29 AM
  3. Replies: 2
    Last Post: 02-26-2009, 11:48 PM
  4. Print function: sending a function.. through a function?
    By scarlet00014 in forum C Programming
    Replies: 3
    Last Post: 11-05-2008, 05:03 PM
  5. Replies: 9
    Last Post: 01-02-2007, 04:22 PM