(beginner) using array - ASCII Math - basic encryption

Hello - I'm having a bit of difficulty getting my head around this.

The program takes input straight away (at cmd line?) when the program is started, and this input will provide the key for this encryption.

So I have this part OK. Then I need to convert the string argv[1] into an int array in alphanumeric range so that I can use it in ASCII math later in the program (Well, I guess it's not ASCII if I change the range... still...)

So this is the part that I have written to convert the string key into an array of ints within the range 0 - 26
// make int array for key
	for (int i = 0, n = strlen(key); i < n; i++)
		{
			key[i] = tolower(key[i]);
			keyInt[i] = (key[i] - 'a');
			printf("\nKEY : %d", keyInt[i]);
		}

And it seems to work - the printf is just there to check but it consistently put's out the correct values.

If i use
printf("Check int array %d\n", keyInt[2]);
After the for loop it prints correctly, so I think I can assume that's worked.

Now what I have to do is take a message off the user that needs to be encrypted - I just use GetString(); for this... So far OK ish.

But then it get's to the for loop that iterates through the users message, and increments through the given key. The key is not to change when the message is not alphabetical. so
message = com ! puter
key = tap

message      : com ! puter 

encrypted by : tap   tapta

my for loop to iterate through the message, and manually increment the position of the key is :

// iterate through the users message and encrypt. 
    for(int i = 0, n = strlen(userM); i < n; i++)
    { 
        int conv = userM[i];
    
        if(islower(conv))
        {
            conv = (conv - 97);
            conv = (conv + keyInt[kPos]) % 26;
			conv = (conv + 97);
            printf("%c", conv);
            kPos++;
        }
        else if (isupper(conv))
        {
            conv = (conv - 97); 
            conv = (conv + keyInt[kPos]) % 26;
			conv = (conv + 97);
            printf("%c",conv);
			kPos++;
        }
        else
            printf("%c",conv);
    }

I'm going to stop there because I don't want to flood the post... I'm not expecting anyone to do this for me but I really need help.

cheers

Comments

  • Your program does the same whether the character is upper or lower case. If you want something between 0 and 26 then all you need to do is convert upper to lower before doing the math. But then when it's time to decode how will you know what characters were upper case, or does that matter?
        // iterate through the users message and encrypt. 
        for(int i = 0, n = strlen(userM); i < n; i++)
        { 
            int conv = userM[i];
            if( isalpha(cony) )
            {
                 if(isupper(conv))
                    convy = tolower(convy);
                conv = (conv - 97); 
                conv = (conv + keyInt[kPos]) % 26;
    			conv = (conv + 97);
                printf("%c",conv);
    			kPos++;
            }
            else
                printf("%c",conv);
        }
    
  • Your program does the same whether the character is upper or lower case.....does that matter?

    Hey Dragon :)

    Yeah - the idea is that the program encrypts only alphabetical characters and retains the casing of them. Although the casing of the key shouldn't make a difference -

    HelLO

    should encrypt something just the same as

    heLlo

    I'm scratching my head though because at the moment if I enter a key 'a' and the message 'hello' the program returns 'helbY'

    I don't really see how it's coming to this conclusion. :confused:

    at the moment the for loop starts ( // iterate through the users message and encrypt) and the first thing that happens is that there is a int variable thats set to the value of userMessage

    int conv = userM[i];
    

    Then there are if statements that determine whether or not the int is lower case or upper case (I guess I'm going on the presumption that these lower / upper methods apply to ints as well... ) If the letter is lower case it passes into the first if statement :
    if(islower(conv))
            {
                conv = (conv - 97);
                conv = (conv + keyInt[kPos]) % 26;
    			conv = (conv + 97);
                printf("%c", conv);
                kPos++;
            }
    

    This statement first reduces the value of conv by 97 - this is so that it falls into the range of 0 - 25 and allows me to calculate using the range of 26

    then the value of (conv + keyInt[kPos]) % 26 is assigned to the variable conv. This is to give the amount by which the value should be encrypted... if the letter was b that would be an encryption value of 1, and would turn c to d, f to g etc...

    Then conv value is incremented by 97, this puts it back into the ASCII range for the next process.

    conv is then printed out to the console.

    kPos is incremented by 1 - this means that the next iteration of the for loop will use the next element in the encryption key's array. So if the key was 'dog' the first value would be 'd', and after this if statement it would be using the 'o'. These increments only happen when the character is alphabetic (or within an ASCII alphabetic range) so that the key position doesn't change for spacing or !?!?! marks.


    So.... I don't really see where the output of 'helbY' is coming from if the key is 'aaa'...

    I think I'm having trouble because the value of kPos (that's the value that adjusts the element of the key used. So if kPos is 2 and the key was 'mouse' the keyInt[kPos] would be 'u')

    So I need to have a way to wrap the kPos around each time it increments past the value strlen(keyInt)

    Hmm... I thought I'd replied to this ages ago but it was just on preview!! Sorry... Hope I've shown what I'm getting / not getting.

    Thanks.
  • Will you post the entire function(s) so that I can test it myself.
  • Will you post the entire function(s) so that I can test it myself.

    Yes sorry, didn't want to put 'too much' up.

    Here's the whole program though :
    #include <cs50.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    /*Shift letters only : isalpha*/
    /*Preserve capitalisation : isupper, islower*/
    
    
    int main(int argc, string argv[])
    {
        
        // check correct number of arguments
        if (argc != 2)
        {
            printf("Incorrect, please restart and enter one positive integer\n");
            return 1;
        }
        
    	// Make Key and convert key to int in alpha range. 
    	string key = argv[1];
    	int l = strlen(key);
    	int keyInt[l]; 
    	int kPos = 0;
    	
    	// make int array for key
    	for (int i = 0, n = strlen(key); i < n; i++)
    		{
    			key[i] = tolower(key[i]);
    			keyInt[i] = (key[i] - 97);
    			printf("\nKEY : %d", keyInt[kPos]);
    		}
        printf("\n");
        
        // get message from user
    	printf("input string to cypher \n");
        string userM = GetString();
        printf("User string : %s\n",userM);
        
        
        
        // iterate through the users message and encrypt. 
        for(int i = 0, n = strlen(userM); i < n; i++)
        { 
            int conv = userM[i];
        
            if(islower(conv))
            {
                conv = (conv - 97);
                conv = (conv + keyInt[kPos]) % 26;
    			conv = (conv + 97);
                printf("%c", conv);
                kPos++;
                
            }
            else if (isupper(conv))
            {
                conv = (conv - 97); 
                conv = (conv + keyInt[kPos]) % 26;
    			conv = (conv + 97);
                printf("%c",conv);
    			kPos++;
            }
            else
                printf("%c",conv);
        }
        
        
        printf("\n");
        return 0;
        
        
            
    }  
    
  • Looks like line 51 is indexing beyond the bounds of the array. If the key is "aaa" then the length of the array keyInt is 3. If you enter "hello" then the loop on line 51 will index from 0 to 4. You can't do that. The key needs to be at least as long as strlen(userM). Your program works if key is "aaaaaaaaaa" and I enter "hello".
  • Looks like line 51 is indexing beyond the bounds of the array. If the key is "aaa" then the length of the array keyInt is 3. If you enter "hello" then the loop on line 51 will index from 0 to 4. You can't do that. The key needs to be at least as long as strlen(userM). Your program works if key is "aaaaaaaaaa" and I enter "hello".

    It can be done if the key wraps back around (though that might not be apparent from this program)

    Example :

    Key = dog

    message = hello mate

    these message letters                    hello mate
    
    will be encrypted by these               dogdo dogd                
    key letters
    

    So (after ASCII values have been reduced to alpha range) 'h' (7) will be shifted by the value of 'd' (3) giving an output of k (10)

    e (4) will be shifted by 0 (14) giving an output of s (18)

    When the space between the words is reached the program doesn't perform and encryption - and the key letter isn't used until an alpha character is met.

    Does that make sense?

    cheers
  • Whoop OK I've got it working :)

    I added a modulo sum to the kPos as part of the encryption if statements and now it works. (line 61 & 72)

    Here's the full program :
    #include <cs50.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    /*Shift letters only : isalpha*/
    /*Preserve capitalisation : isupper, islower*/
    
    
    int main(int argc, string argv[])
    {
        
        // check correct number of arguments
        if (argc != 2)
        {
            printf("Incorrect, please restart and enter one positive integer\n");
            return 1;
        }
        
        //check that the key is all alphabetic. 
        for(int i = 0, n = strlen(argv[1]); i < n; i++)
        {
            if(!isalpha(argv[1][i]))
            {
                printf("Only use");
               return 1;
            }
        }
        
    	// Make Key and convert key to int in alpha range. 
    	string key = argv[1];
    	int l = strlen(key);
    	int keyInt[l]; 
    	int kPos = 0;
    	
    	// make int array for key
    	for (int i = 0, n = strlen(key); i < n; i++)
    		{
    			key[i] = tolower(key[i]);
    			keyInt[i] = (key[i] - 'a');
    		}
        
        // get message from user
        string userM = GetString();
        
        
        
        // iterate through the users message and encrypt. 
        for(int i = 0, n = strlen(userM); i < n; i++)
        { 
            int conv = userM[i];
        
            if(islower(conv))
            {
                conv = (conv - 'a');
                conv = (conv + keyInt[kPos]) % 26;
    			conv = (conv + 'a');
                printf("%c", conv);
                kPos++;
                kPos = (kPos%strlen(key));
    	
                
            }
            else if (isupper(conv))
            {
                conv = (conv - 'A'); 
                conv = (conv + keyInt[kPos]) % 26;
    	    conv = (conv + 'A');
                printf("%c",conv);
    			kPos++;
    			kPos = (kPos%strlen(key));
    	
            }
            else
                printf("%c",conv);
        }
        
        
        printf("\n");
        return 0;
        
        
            
    }  
    
    



    Would appreciate any feedback re overall design though - anything that's a bit convoluted / hard to read or bad practice would be great to have highlighted.

    Cheers
Sign In or Register to comment.