Thread: Vigenere encryption/decryption program.

  1. #1
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357

    Vigenere encryption/decryption program.

    Hello to all

    I am trying to make a program that implements the Vigenere known algorith for cryptography ...

    Vigenère cipher - Wikipedia, the free encyclopedia

    I have done the lot of the job ... But i have to throw out the characters that they aren't valid letters after I will give the choice to user to give text from terminal or from a file. Anyway for now I have done this :

    Code:
    /********************************************
     * Description: Simple Vigenere example program
     * Licence : Public 
     * ******************************************/
    #include<stdio.h>
    #include<ctype.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAX_ROWS 26
    #define MAX_COLS 26
    #define MAX_LEN_PLAINTEXT 30 + 1
    #define MAX_LEN_KEY 30 + 1
    #define S_CHAR 'A'  // Starting char of latin alphabet
    #define E_CHAR 'Z'  // Ending char of latin alphabet
    #define MOD 26
    #if 1
    #define INFO "*****************************************\n"\
    			 "* Author: Kwstas Tsit                   *\n"\
    			 "* Email: [email protected]            *\n"\
    			 "* Date: 19/12/2014                      *\n"\
    			 "* Type : Encryption/Decryption          *\n"\
    			 "* Method: Vigenere Algorithm            *\n"\
    			 "* More info: Google Vigenere Algorithm  *\n"\
    			 "*****************************************\n"\
    
    #define CRYPTO_LABEL " *******   ******  *   *   ***** *******   *******\n" \
                         "*          *    *  *   *   *   *    *      *     *\n" \
                         "*          ******  *****   *****    *      *     *\n" \
                         "*          **        *     *        *      *     *\n" \
                         "*******    * *       *     *        *      *******\n" \
    
    #endif
                          
    char *vigenere_crypto( char *plaintext, char *key);
    char *vigenere_decrypto( char *encrypted , char *key);
    void tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] );
    void print_tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] );
    int read_line( char *str , int n);
    char* key_repeat( char *key , char *plaintext , int KeyLen );
    
    char tabula_recta[MAX_ROWS][MAX_COLS];
    
    /*************************************************
     *  main function , call the subroutines 
     *  of tab_recta table , encryption - decryption.
     * ***********************************************/
     
    int main(void)
    {
    	char plaintext[MAX_LEN_PLAINTEXT]={'\0'};
    	char *key = NULL;
    	int KeyLen;
    	
    	printf("%s" , CRYPTO_LABEL); 
    	printf("\n %s" , INFO);
    	
    	tab_recta( tabula_recta );
    	printf("\n");
    	//print_tab_recta( tabula_recta );
    	printf("Give the plaintext(up to 30 characters) : ");
    	read_line( plaintext , MAX_LEN_PLAINTEXT ); //read the message.
    	
    	key = calloc (MAX_LEN_KEY , sizeof(char));
    	if( key == NULL ){
    		printf("Error: malloc faild in key");
    		exit(EXIT_FAILURE);
    	}
    
    	printf("Give the key: ");
    	KeyLen = read_line( key , MAX_LEN_KEY );  // the actual length of user's key. 
    
    	key_repeat( key , plaintext , KeyLen );  // key repeat if it is necessary.
    	puts(key);
    	
    	printf("\n Cipher: %s " , vigenere_crypto(plaintext, key) );
    	printf("\n Plaintext: %s ", vigenere_decrypto( plaintext , key) );
    	
    	free(key);
    	
    	return 0;
    }
    /********************************************************
     *  tab_recta table filling function , uses an 2D array
     *  in order to make the tab_recta square table.
     * ******************************************************/
    void tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] )
    {
    	
    	int pos , row , col;
    	
    	for( row=0; row < MAX_ROWS; row++){
    		pos = 0;
    		for( col=0; col < MAX_COLS; col++){
    			if( S_CHAR+row+col > E_CHAR && row > 0){
    				tabula_recta[row][col] = S_CHAR + pos;
    				pos++;
    			}
    		    else 
    			tabula_recta[row][col] = S_CHAR+row+col;
    		}
    	}
    	
    	return;
    }
    /***********************************************
     *  Function that prints the contents of
     *  tabula_recta square if you want it.
     * *********************************************/
    #if 0
    void print_tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS])
    {
    	int row , col;
    	
    	for( row=0; row<MAX_ROWS; row++) {
    		printf("\n");
    		for( col=0; col<MAX_COLS; col++){
    				printf("%c" , tabula_recta[row][col]);
    		}
    	} 	
    
    	return;
    }
    #endif 
    /********************************************
     *  vigenere_crypto makes the encryption 
     *  The contents come from tabula_recta square
     *  it takes the plaintext as argument and the
     *  key in order to do the encryption procedure
     *  returns the encrypted string of your msg.
     * ******************************************/
    char *vigenere_crypto(char *plaintext , char *key)
    {
    	int row_tab_rec , col_tab_rec , i=0;
    	char *encrypted = plaintext; 
    	
    	while( encrypted[i] ){
    		row_tab_rec = (key[i] - S_CHAR )%MOD;  // For the apropriate row.
    		col_tab_rec = (plaintext[i] - S_CHAR )%MOD; // For the apropriate column.
    		encrypted[i] = tabula_recta[row_tab_rec][col_tab_rec]; // The element of the tabula recta square.
    		i++;
    	}
    		
    	return encrypted;
    }
    /****************************************************
     *  vigenere_decrypto function makes the decryption
     *  in order to gve you the plaintext. It takes 
     *  the encrypted msg and the key. It produces the
     *  decrypted message.
     *  It returns the decrypted string which is the 
     *  previous plaintext.
     * *************************************************/
    char *vigenere_decrypto(char *encrypted , char *key)
    {
    	int i=0;
    	
    	char *decrypted = encrypted;
    	
    	while( encrypted[i] ) {
    		if( encrypted[i] >= key[i] ) 
    			decrypted[i] = encrypted[i] - (key[i]- S_CHAR)%MOD; 
    		
    		else if ( encrypted[i] < key[i] )  
    			decrypted[i] = E_CHAR + 1 - (key[i] - encrypted[i]) ;	
    		i++;
    	}
    	
    	return decrypted;
    }
    int read_line( char *str , int n)
    {
    	int ch , i=0;
    	while( isspace( ch = getchar() ))
    			;
    	while( ch!= '\n' && ch != EOF) {
    			if( i < n)
    				str[i++] = ch;
    				ch = getchar();
    	}
    	str[i] ='\0';
    	
    	return i;
    }
    char *key_repeat( char *key , char *plaintext , int KeyLen)
    {
        char *tmp = calloc( KeyLen + 1, sizeof(char));
        int P_Len = strlen(plaintext); // P_Len is the length of your original message.
        int i=0;
        
        if( tmp == NULL ){
    		printf("Error: calloc faild in key_repeat.");
    		exit(EXIT_FAILURE);
    	}
    
    	strcpy( tmp , key);
    	if ( KeyLen == P_Len)  // same length of key and plaintext.
    		return key;
    	// length of key is greater than plaintext.	
    	else if ( KeyLen > P_Len ) {
    		key[ P_Len ]= '\0';
    		return key;
    	}
    	// length of key is lower than plaintext. 
    	else {
    		// move the key to null character. 
    		while( *key ){  
    			  key++;
    			  plaintext++;
    		}
    		// repeat the key in order to be the same in length with plaintext.
    		while( *plaintext ) { 
    			// if the plaintext has same length with the repeat of the key.
    			 if( P_Len % KeyLen == 0 ) { 
    				strcpy( key , tmp); // repeat the key. Copy the blocks of KeyLen sized.
    				key += KeyLen;  // increase the key to its length.
    				plaintext += KeyLen;   
    			 }
    			 // if the plaintext has no the same length with the repeat of the key.
    			else if( P_Len % KeyLen != 0 ) {
    				*key= *tmp;  // copy each character.
    				 key++;	tmp++; i++; // move the pointers and the counter.
    			if( i == KeyLen) { 
    				tmp -= KeyLen; i=0;  // move back the tmp pointer to the start of key. 
    		     }
    		     plaintext++;
    		   }
    	   }
    	}
    	free(tmp);  // Why here I took an error message?
    	return key;
    }
    I have done the checks in the following situations :
    • the key has the same length with the plaintext.


    • key is greater than plaintext (the lengths)


    • key is lower ... and when if the length of the key is divided with the length of the plaintext and or not.


    I didn't have problems with the tests. But When I put the free(tmp) into the key_repeat function I had problems... I took a common error sush as :

    Code:
    *** glibc detected *** ./a.out: free(): invalid next size (fast): 0x09f931f0 ***
    ======= Backtrace: =========
    /lib/libc.so.6(+0x6c501)[0x3de501]
    /lib/libc.so.6(+0x6dd70)[0x3dfd70]
    ....
    - What is your opinion about my code?
    - What is the problem????

    thank you in advance.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > key = calloc (MAX_LEN_KEY , sizeof(char));
    This needs to be as long as your plaintext, given what you're attempting to do in key_repeat()

    key_repeat itself is massively overengineered (and just plain wrong).
    Have a look at this.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    void extend(char *plain, char *key) {
      size_t plen = strlen(plain);
      size_t klen = strlen(key);
      if ( plen <= klen ) {
        key[plen] = '\0';
      } else {
        char  *k2 = key, *k3 = key+klen;
        plain += klen;
        while ( *plain++ != '\0' )
          *k3++ = *k2++;
        *k3 = '\0';
      }
    }
    
    int main ( ) {
      char plain[100] = "this is a long piece of text";
      char key[100] = "key";
      extend(plain,key);
      printf("%s\n",plain);
      printf("%s\n",key);
      return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    thank you for your answer but what do you mean by "it is massively overengineered?" it is impossible to make some correction and use the function again? I should delete it and use your version?
    Last edited by Mr.Lnx; 12-21-2014 at 02:07 PM.

  4. #4
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    I Think now it is ok. Your version is better because it is more simple. I have the problem that I am writing codes that they are complex sometimes ...

    Code:
    /* NEW vERSION.... */
    
    /********************************************
     * Description: Simple Vigenere example program
     * Licence : Public 
     * ******************************************/
    #include<stdio.h>
    #include<ctype.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAX_ROWS 26
    #define MAX_COLS 26
    #define MAX_LEN_PLAINTEXT 30 + 1
    #define S_CHAR 'A'  // Starting char of latin alphabet
    #define E_CHAR 'Z'  // Ending char of latin alphabet
    #define MOD 26
    #if 1
    #define INFO "*****************************************\n"\
    			 "* Author: Kwstas Tsit                   *\n"\
    			 "* Email: [email protected]            *\n"\
    			 "* Date: 19/12/2014                      *\n"\
    			 "* Type : Encryption/Decryption          *\n"\
    			 "* Method: Vigenere Algorithm            *\n"\
    			 "* More info: Google Vigenere Algorithm  *\n"\
    			 "*****************************************\n"\
    
    #define CRYPTO_LABEL " *******   ******  *   *   ***** *******   *******\n" \
                         "*          *    *  *   *   *   *    *      *     *\n" \
                         "*          ******  *****   *****    *      *     *\n" \
                         "*          **        *     *        *      *     *\n" \
                         "*******    * *       *     *        *      *******\n" \
    
    #endif
                          
    char *vigenere_crypto( char *plain, char *key);
    char *vigenere_decrypto( char *encrypted , char *key);
    void tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] );
    void print_tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] );
    int read_line( char *str , int n);
    void key_repeat( char *key , char *plain);
    
    char tabula_recta[MAX_ROWS][MAX_COLS];
    
    /*************************************************
     *  main function , call the subroutines 
     *  of tab_recta table , encryption - decryption.
     * ***********************************************/
     
    int main(void)
    {
    	char plain[MAX_LEN_PLAINTEXT]={'\0'};
    	char key[MAX_LEN_PLAINTEXT]={'\0'};
    	
    	printf("%s" , CRYPTO_LABEL); 
    	printf("\n %s" , INFO);
    	
    	tab_recta( tabula_recta );
    	printf("\n");
    	//print_tab_recta( tabula_recta );
    	printf("Give the plaintext(up to 30 characters) : ");
    	read_line( plain , MAX_LEN_PLAINTEXT ); //read the message.
    	printf("Give the key: ");
    	read_line( key , MAX_LEN_PLAINTEXT );  // the actual length of user's key. 
        
    	key_repeat( plain , key);  // key repeat if it is necessary.
    	puts(key);
    	
    	printf("\n Cipher: %s " , vigenere_crypto(plain, key) );
    	printf("\n Plaintext: %s ", vigenere_decrypto( plain , key) );
    	
    	return 0;
    }
    /********************************************************
     *  tab_recta table filling function , uses an 2D array
     *  in order to make the tab_recta square table.
     * ******************************************************/
    void tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS] )
    {
    	
    	int pos , row , col;
    	
    	for( row=0; row < MAX_ROWS; row++){
    		pos = 0;
    		for( col=0; col < MAX_COLS; col++){
    			if( S_CHAR+row+col > E_CHAR && row > 0){
    				tabula_recta[row][col] = S_CHAR + pos;
    				pos++;
    			}
    		    else 
    			tabula_recta[row][col] = S_CHAR+row+col;
    		}
    	}
    	
    	return;
    }
    /***********************************************
     *  Function that prints the contents of
     *  tabula_recta square if you want it.
     * *********************************************/
    #if 0
    void print_tab_recta( char tabula_recta[MAX_ROWS][MAX_COLS])
    {
    	int row , col;
    	
    	for( row=0; row<MAX_ROWS; row++) {
    		printf("\n");
    		for( col=0; col<MAX_COLS; col++){
    				printf("%c" , tabula_recta[row][col]);
    		}
    	} 	
    
    	return;
    }
    #endif 
    /********************************************
     *  vigenere_crypto makes the encryption 
     *  The contents come from tabula_recta square
     *  it takes the plaintext as argument and the
     *  key in order to do the encryption procedure
     *  returns the encrypted string of your msg.
     * ******************************************/
    char *vigenere_crypto(char *plaintext , char *key)
    {
    	int row_tab_rec , col_tab_rec , i=0;
    	char *encrypted = plaintext; 
    	
    	while( encrypted[i] ){
    		row_tab_rec = (key[i] - S_CHAR )%MOD;  // For the apropriate row.
    		col_tab_rec = (plaintext[i] - S_CHAR )%MOD; // For the apropriate column.
    		encrypted[i] = tabula_recta[row_tab_rec][col_tab_rec]; // The element of the tabula recta square.
    		i++;
    	}
    		
    	return encrypted;
    }
    /****************************************************
     *  vigenere_decrypto function makes the decryption
     *  in order to gve you the plaintext. It takes 
     *  the encrypted msg and the key. It produces the
     *  decrypted message.
     *  It returns the decrypted string which is the 
     *  previous plaintext.
     * *************************************************/
    char *vigenere_decrypto(char *encrypted , char *key)
    {
    	int i=0;
    	
    	char *decrypted = encrypted;
    	
    	while( encrypted[i] ) {
    		if( encrypted[i] >= key[i] ) 
    			decrypted[i] = encrypted[i] - (key[i]- S_CHAR)%MOD; 
    		
    		else if ( encrypted[i] < key[i] )  
    			decrypted[i] = E_CHAR + 1 - (key[i] - encrypted[i]) ;	
    		i++;
    	}
    	
    	return decrypted;
    }
    int read_line( char *str , int n)
    {
    	int ch , i=0;
    	while( isspace( ch = getchar() ))
    			;
    	while( ch!= '\n' && ch != EOF) {
    			if( i < n)
    				str[i++] = ch;
    				ch = getchar();
    	}
    	str[i] ='\0';
    	
    	return i;
    }
    void key_repeat(char *plain, char *key) {
      size_t plen = strlen(plain);
      size_t klen = strlen(key);
      
      if ( plen <= klen ) {
        key[plen] = '\0';
      } else {  
    	char  *k2 = key, *k3 = key+klen;
        plain += klen;
        while ( *plain++ != '\0' )
          *k3++ = *k2++;
        *k3 = '\0';
      }
    
    }
    If there is any other suggestion about my code I would be grateful ... I want to program well and simple.
    Last edited by Mr.Lnx; 12-21-2014 at 04:05 PM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I think your read_line has the potential for a buffer overflow.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Oops yes you are right. It must be

    Code:
     #define MAX_LEN_PLAINTEXT 30
    Drop the +1.

  7. #7
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Here I am again ....

    I have a basic problem .... I am trying to configure the program in order to make the encryption/decryption in more than one words ...

    Code:
    void key_repeat(char *plain, char *key) {
      size_t plen = strlen(plain);
      size_t klen = strlen(key);
      
      if ( plen <= klen ) {
        key[plen] = '\0';
      } else {  
    	char  *k2 = key, *k3 = key+klen; /* k2 will continue from the first beginning of k3 (after the copy),
    	 so will have already a copy of the key and so forth until the end of plain */
        plain += klen;
        while ( *plain!= '\0') {
    		if( !isalpha(*plain) ) {
    			*k3++ = *plain++;
    			 k2 = key;
    			 continue;
    		}
    		*k3++ = *k2++;  // copy the key to k3 location , repeat the key.
    		plain++;
    	} 
        *k3 = '\0';
       }
      puts(key);
    }
    That is the key function ... the changes in the program is here. The problems that I have is:

    Code:
    
    Give the plaintext(up to 30 characters) : HI MAN
    Give the key: CLOUD
    CLOUDC
    
     Cipher: JTGGDP 
     Plaintext: HISMAN

    I have the problem with the plaintext "HI_MAN" and the CLOUD as the key. I was happy when I tried the "TRUTHWILLOUT_TRUTHWILLOUT" TEXT because the key is exactly what i want for example it was CLOUDCLOUDCL CLOUDCLOUDCL but then I saw that I have problems.I think the problem here is the plain +=klen; but if i change it I think that the code will be broken due to its logic. Any help? thank you in advance.

    The whole code is here :

    http://ideone.com/M4nzrh

    P.S I just want to repeat the key when I have non alphabetic characters between the words.
    Last edited by Mr.Lnx; 12-25-2014 at 06:45 PM.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    So for "HI MAN", do you expect the key to be "CL OUD" or "CL CLO" ?

    Now is a really good time to figure out how to use a debugger.

    Put a breakpoint on this line if( !isalpha(*plain) )

    Call the function with a small test case, like "A B" and "KEY"

    At reaching the breakpoint, set up watch windows for the interesting variables, then
    - explain to yourself what you expect the next line to do
    - single-step the line of code and observe what happens.

    Every time you're surprised by the result, STOP and have a really long think about what you wrote, and what you expect to achieve. Every surprise is a bug - whether that bug is in the code, or your understanding of the language or the problem is for you to figure out.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    I expect the key to be "CL CLO"

    The problem here is that plain points to 'N' so the key would be CLOUDC and then while( *plain != '\0') would be true , in addition I have no any problem with the input "HEYYY MAN" it works exactly as I want. The problem is where the word is less than key. In this case HEYYY and CLOUD has the same length so there is no problem.

    my question: is there a way to solve the problem with your code or I should change all the function?

    I have clear view what the problem is every time I don't need a debugger for this except you suggest debugger for other reason.... Thank you for your time
    Last edited by Mr.Lnx; 12-26-2014 at 05:31 AM.

  10. #10
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    The issue now is that if you have non-alphabetic characters in your string the repeating part of the key will also repeat those characters because the key is reading itself.

    Example:
    Code:
    Give the plaintext(up to 30 characters) : HELP ME PLEASE
    Give the key: TEST
    TEST TE ST TE
    What is happening here is that the space is being written to the key, then the copy pointer reads that space and copies it back into the key again just like it was copying the TEST letters. So the space becomes part of the repeating pattern corrupting the result.

    As far as handling the case where you have a space in the plain text that is shorter than the length of the key, you could handle that by just finding the position of the space in the plain text and then change those positions in the key string to a space also. You could handle both cases with the same code though if you re-factor a little bit.

  11. #11
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Well I was mistaken.... the right way is : CL_OUD not CL_CLO if I have HI_MAN as a plaintext. Sorry Salem.

    I found that

    Encyclopedia Britannica

    @nonpuz I will follow your advice tonight

    thank you.

  12. #12
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    I think at this point it'd be best to simply copy the key to a buffer, then rewrite the entire key as you go through the plain text, copying strings from the copy or the plain text depending on if it's alphabetic or not. Why not pass it through a toupper() filter too so you can enter messages in lower case and it will still work.

  13. #13
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by nonpuz View Post
    I think at this point it'd be best to simply copy the key to a buffer, then rewrite the entire key as you go through the plain text, copying strings from the copy or the plain text depending on if it's alphabetic or not. Why not pass it through a toupper() filter too so you can enter messages in lower case and it will still work.
    The original version of Salem you think that will change? I am confused .. fixing one case broking down the other :/

  14. #14
    Ultraviolence Connoisseur
    Join Date
    Mar 2004
    Posts
    555
    Salems code worked fine when you didn't have any spaces in your strings. With spaces it causes those spaces to be repeated as I showed you earlier.

    To fix that you would need to insert spaces into the key string, shifting all letters after the insertion one space forward, then on reading the repeated part of the string you will have to skip over those spaces when copying to itself (if that makes sense..)

    I think it would be simplier to copy the string to another buffer first, then read from that. Like so:
    Code:
    void key_repeat(char * plain, char * key) 
    {
        size_t len = strlen(key);
        char * copy = malloc(len + 1); 
            
        /* Copy to internal buf or memory buf if possible */
        if (!copy)
            return;
        strcpy(copy, key);
    
        for (size_t i = 0; *plain; ++plain, ++key) 
            *key = !isalpha(*plain) ? *plain : copy[i++ % len];
        *key = '\0';
    
        free(copy);
    }
    Last edited by nonpuz; 12-27-2014 at 11:05 AM. Reason: Removed return statement from an iteration i had where the function returned int instead of void

  15. #15
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Thank you very much for your help nonpuz

    I knew the problem but I faced difficulties on how to write the code. I didn't bear in my mind the possibility-> copy[i%len].
    I am good to read and understand others code but it is not the same when you are called to write your own. I hope in the future with more practice to be better on this

    thank you again for all. Happy new year

    P.S The whole program if you have any suggestion I would be grateful

    Ideone.com - avjk3u - Online C Compiler & Debugging Tool
    Last edited by Mr.Lnx; 12-27-2014 at 03:16 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with encryption/decryption program
    By pantherprowl06 in forum C Programming
    Replies: 5
    Last Post: 11-29-2013, 01:17 PM
  2. Encryption/Decryption Program
    By adohertyd in forum C Programming
    Replies: 8
    Last Post: 12-21-2011, 02:00 PM
  3. Vigenere Cipher decryption help needed
    By magic101 in forum C Programming
    Replies: 2
    Last Post: 02-07-2009, 07:25 PM
  4. encryption / decryption program
    By epidemic in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2008, 06:40 AM
  5. Encryption and Decryption Program in C++ using a class
    By goron350 in forum C++ Programming
    Replies: 7
    Last Post: 06-05-2005, 09:29 PM