用C语言构建一个Caesar密码解码器

时间:2015-10-14 00:10:28

标签: c

我是C的新手,这对于来来往往的作业来说是一个额外的问题,但我仍然试图通过它进行拼图。

目的是接受来自使用Caesar Cipher编码的文件的输入(在字母表中向左或向右移动字母),找出具有最高频率的字母然后使用此来猜测移位值并解码输入。

我分别设法读取频率并计算移位值,然后使用此结果解码输入。但是当我把所有东西放在一个文件中时,我无法使它工作。 事实上,除了通过main和打印Success1之外,它现在甚至看起来都没有做任何事情。

关于如何改进这个或者它不起作用的原因的任何建议都会很棒。我觉得我大概有90%,但不知道最后10%。

感谢。

int count_freq( int count[] );
int decode( int shift, int ch );
int rotate_right( int ch );
int rotate_left( int ch );

                                                                               // count the number of occurrences of each letter
int count_freq( int count[] )
{
  int ch;
  int shift, maximum, size = 26, c, location = 1, i;

  while(( ch = getchar()) != EOF ) 
    {
        ch = toupper( ch );                                                     // convert to upper case
        if( ch >= 'A' && ch <= 'Z' ) 
        {
            i = ch - 'A';
            count[i]++;                                                         // increment i'th element
        }
    } 

    maximum = count[26];                                                        //Sets maximum size of count

    for( c = 1; c < size; c++ )
    {
        if( count[c] > maximum )                                                //not 100% sure what is happening here but it works
        {
          maximum = count[c];
          location = c+1;
        }
    }

    shift = 5-(location-1);                                                     //Compares the value of the letter with the highest frequency to E to find the shift
    return(shift);
    printf("shift = %d", shift );
    printf("Success2"); 
}

int decode( int ch, int shift)
{
    int j;
     if( shift >= 0 ) 
    {                                                                           //If shift is greater than zero
           for( j=0; j < shift; j++ )                                           //Start at i=0, increment by one while i is less than shift
           {              
                     ch = rotate_right( ch );                                   //Use the function that increases the characters
           }
    }
    else 
    {                                                                           //For shifting values less than zero      
           for( j=0; j < -shift; j++ )                                          //Start at i=0, increment by one while i is less than negative shift (ie. if shifting value is -10 this goes up to i=10)
           {                 
                     ch = rotate_left( ch );                                    //Use the function that decreases the characters        
           }
    }

    printf("Success3");     
}

int rotate_right( int ch )
{
   if( ch == 'Z' ) {                                                            //If the character is Z then make it A
      return( 'A' );
   }
   else if( ch == 'z' ) {                                                       //Same for lower case
      return( 'a' );
   }
   else if(  ( ch >= 'A' && ch < 'Z' )                                          //If the Character is greater than or equal to A and less than Z, add one to the value of the character. Eg. B -> C
           ||( ch >= 'a' && ch < 'z' )) {
      return( ch + 1 );
   }
   else {                                                                       //This is for the characters that are not letters. Punctuation and spaces
      return( ch );
   }
   printf("Success4");
}

int rotate_left( int ch )                                                       //This is all the same but it shifts the value of the characters the other way. Eg. C -> B                   
{
   if( ch == 'A' ) {
      return( 'Z' );
   }
   else if( ch == 'a' ) {
      return( 'z' );
   }
   else if(  ( ch > 'A' && ch <= 'Z' )
           ||( ch > 'a' && ch <= 'z' )) {
      return( ch - 1 );
   }
   else {
      return( ch );
   }
   printf("Success5");
}

int main( )
{
    int count[26] = { 0 };                                                      //Initialize array elements
    int ch, shift;
    count_freq( count );                                                        //Count frequencies

    while(( ch = getchar()) != EOF )                                            //While the variable ch is not the end of the string entered
    {     
         putchar( decode( ch, shift ));                                         //Calls the decode function from above using ch from getchar and shift from scanf 
    }

    printf("Success1");
    return 0;
}

3 个答案:

答案 0 :(得分:2)

至少,您的代码不起作用,因为decode()中没有返回语句。

如果你的编译器没有对此发出警告/错误,你应该得到一个更好的编译器。

答案 1 :(得分:2)

我注意到的第一件事是:

致电shift

时,您永远不会使用初始化count_freq()

因此,当您将shift传递给解码时,它会作为堆栈中任何内容的垃圾值传递。

答案 2 :(得分:1)

您需要使用模数运算符%来移位字符

result = 'A' + (c - 'A' + shift) % 26

% 26确保没有角色超出范围。

如果shift为2且字符为'A'=&gt;结果是'C'

如果shift为2且字符为'Z'=&gt;结果是'B'

要对邮件进行解码,请将shift更改为26 - shift

void rotate(char* msg, int shift)
{
    for (int i = 0, len = strlen(msg); i < len; i++)
    {
        if (msg[i] >= 'a' && msg[i] <= 'z')
            msg[i] = 'a' + (msg[i] - 'a' + shift) % 26;
        else if (msg[i] >= 'A' && msg[i] <= 'Z')
            msg[i] = 'A' + (msg[i] - 'A' + shift) % 26;
    }

    printf("%s\n", msg);
}

void encode(char* msg, int shift)
{
    rotate(msg, shift);
}

void decode(char* msg, int shift)
{
    rotate(msg, 26 - shift);
}

int main()
{
    char message[100];
    strcpy(message, "ABCD XYZ");
    encode(message, 2);
    decode(message, 2);
    return 0;
}