2016-10-05 19 views
-1

私はcs50 pset2で作業していましたが、数日間作業した後にvigenere暗号がダウンしていると思いました。このコードは、ユーザーから与えられたアルファベットの引数(argv [])を取り、それをアルファベット順インデックスの数字でユーザー(文字列)が指定した句を暗号化するキーとして使用するためのものです。たとえば、引数 'abc'と文字列 'cat'を指定すると、出力は 'cbv'(移動0、b移動1、c移動2)になります。より長い場合、引数は最初の文字にラップされ、文字列が終了するまで続きます。Vigenere Cipher。コード出力

これは私がコードを持っているものです。

#include <cs50.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 


int main(int argc, string argv[]) 
{ 


    if(argc != 2) 
     { 
      printf("Try again\n"); 
      return 1; 
     } 
    string k = (argv[1]); 

    int klen = strlen(k); 


    for(int x = 0; x < klen; x++) 
     { 
      if(isalpha(k[x])) 
       { 
        if(isupper(k[x])) 
         { 
          k[x] = tolower(k[x]); 
         } 

         k[x] -= 'a'; 
       } 
      else 
       { 
        printf("Try again\n"); 
        return 1; 
       } 
     } 

    string code = GetString(); 

    int clen = strlen(code); 

    for(int a = 0, b = 0; a < clen; a++) 
     { 
      if(isalpha(code[a])) 
       { 
        int key = k[b%klen]; 
        if(isupper(code[a])) 
         { 
          printf("%c", (((code[a] - 'A') + key)%26) + 'A'); 
          b++; 
         } 
        else 
         { 
          printf("%c", (((code[a] - 'a') + key)%26) + 'a'); 
          b++; 
         } 
       } 
      else 
       { 
        printf("%c", code[a]); 
       } 
     } 
    printf("\n"); 
} 

コードは、キー1の長さのために働くようです。例えば 、その後 I入力「AAAA」

の引数を入力「BBBBB」 の文字列と正確に「BBBBB」受け取ります。しかし

、私はその後、入力と同じ「AAAA」

を長い文字列のキー+1「BBBBBBB」 より入力私は私が私のために問題を持っていると信じて「bbbbbNN」

を受信した場合括弧が動かないようにしようとしました。私は誰かが私の鍵が適切にラップされていない理由を正しい方向に向けることができると願っていました。

+0

私はあなたの入力のためにこれを再現することはできません 'aaaa'と' bbbbbbb'、私はちょうど '割り当て、任意の' STRING'タイプを使用していないが、するchar * K =のargv [:それはあなたのための任意のより良い動作するかどうかを参照してください。 1]; 'と' char * code = argv [2]; '残りはあなたが投稿した通りです。 –

+1

あなたの3番目のprintfは 'printf("%c "、((code [a] - 'a')+(k)]でなければならないと思います。 [b%klen] - 'A'))%26)+ 'a'); '。 –

+0

ボブ、それに感謝します。それは間違いなく問題の一部でした。私は自分のコードを更新しましたが、 'bbbbbNN'の代わりに' bbbbbhh'を取得しています。まだコードの周りにキーをラップするのに問題があるようです。 –

答えて

0

このようなコードで最も危険なのは、すべて同様の反復節です。ただ一つのバグは追跡が難しいです。そして、コードを処理している間にキーに対する処理を行うことは、単に非効率的です。

コードを処理する前にキーを完全に処理し、処理を1つだけにしようとするリワークです。

#include <cs50.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <stdlib.h> 

int main(int argc, string argv[]) 
{ 

    if (argc != 2) 
    { 
     fprintf(stderr, "Try again\n"); 
     return EXIT_FAILURE; 
    } 

    string key = strdup(argv[1]); 

    size_t key_length = strlen(key); 

    for (int x = 0; x < key_length; x++) 
    { 
     if (isalpha(key[x])) 
     { 
      if (isupper(key[x])) 
      { 
       key[x] = tolower(key[x]); 
      } 

      key[x] -= 'a'; 
     } 
     else 
     { 
      fprintf(stderr, "Try again\n"); 
      return EXIT_FAILURE; 
     } 
    } 

    string code = GetString(); 
    int code_length = strlen(code); 

    for (int a = 0, b = 0; a < code_length; a++) 
    { 
     if (isalpha(code[a])) 
     { 
      int start = isupper(code[a]) ? 'A' : 'a'; 

      printf("%c", (((code[a] - start) + key[b++ % key_length]) % 26) + start); 
     } 
     else 
     { 
      printf("%c", code[a]); 
     } 
    } 

    printf("\n"); 

    free(key); 

    return EXIT_SUCCESS; 
} 
+0

応答をありがとう。私はまだこれまでにはまだ新しく、あなたが書いたことのいくつかを理解していませんが、コードの前に鍵セットを取得して何が起こるかを見てみましょう。 –

+0

私はあなたのアドバイスを受け取り、コードループの外側でキーを処理して動作します!それはまだ少し厄介で簡素化することができますが、少なくとも今は機能しており、効率を改善するために取り組むことができます。再度、感謝します。 –