2017-01-07 111 views
-2

我在做家庭作業時遇到了麻煩。
我正在做一個可以加密和解密的RSA應用程序。RSA加密C代碼

問題是,我輸入的東西加密後,結果很奇怪,我無法解密任何東西。這是因爲當我複製符號加密的結果時,我得到了更多奇怪的東西。

我猜它與我的公式得到負面的ASCII作爲結果有關。

下面是我試過了,並且,以瞭解我的意思的怪異,只是編譯並嘗試一下(我有我還沒有刪除一些不用的東西):
輸出


Encrypting kevin After Copying encrypted kevin to decrypt

代碼

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <math.h> 
#define boolean int 
#define true 1 
#define false 0 
//===================================================// 
int p = 0; 
int q = 0; 
int n = 0; 
int m = 0; 
int divider = 2; 
int tempdivider = 2; 
int initial = 0; 
int x = 0; 
int y = 0; 
char msg[100]; 
char alphabet[27]; 
//===================================================// 
void cls(); 
void menu(); 
void init(); 
void reinit(); 
void inputencrypt(); 
//int encrypt(int num); 
void encrypt(); 
char decrypt(char text[]); 
int fpb(int num); 
int d(int num); 
int primecheck(int a); 
boolean checkdigit(char text[]); 
//===================================================// 

int main() { 
    frontpage(); 
    init(); 
    menu(); 
    getchar(); 
    return 0; 
} 
//===================================================// 
void cls() { 
    for (int i = 0;i < 25;i++) { 
     printf("\n"); 
    } 
} 
//===================================================// 
boolean checkdigit(char text[]) { 
    int len = strlen(text); 
    for (int i = 0;i < len;++i) { 
     if (text[i]<'0' || text[i]>'9') { 
      return false; 
     } 
    } 
    return true; 
} 
int primecheck(int a) { 
    if (a == 1) { 
     return false; 
    } 
    for (int i = 2;i < a;i++) { 
     if (a%i == 0) { 
      return false; 
     } 
    } 
    return true; 
} 
//===================================================// 
void reinit() { 
    for (int i = 1;i < 27;i++) { 
     alphabet[i] = 'a' + i - 1; 
    } 
    p = 0; 
    q = 0; 
    n = 0; 
    m = 0; 
    divider = 2; 
    tempdivider = 2; 
    initial = 120; 
    x = 0; 
    y = 0; 
} 
void init() { 
    reinit(); 
    do { 
     printf("p = "); 
     scanf("%d", &p);fflush(stdin); 
     if (!primecheck(p)) { 
      printf("must be prime number! \n"); 
     } 
    } while (!primecheck(p)); 
    do { 
     printf("q = "); 
     scanf("%d", &q);fflush(stdin); 
     if (!primecheck(q)) { 
      printf("must be prime number! \n"); 
     } 
    } while (!primecheck(q)); 
    n = p*q; 
    m = (p - 1)*(q - 1); 
    initial = m; 
    x = fpb(m); 
    y = d(m); 
    printf("n = %d\n", n); 
    printf("m = %d\n", m); 
    printf("e = %d\n", x); 
    printf("d = %d\n", y); 
    system("pause"); 
} 
//===================================================// 
void menu() { 
    char input[2]; 
    int input1 = 0; 
    do { 
     do { 
      cls(); 
      printf("main menu\n"); 
      printf("================\n"); 
      printf("1. encrypt\n"); 
      printf("2. decrypt\n"); 
      printf("3. exit\n"); 
      printf(">> "); 
      scanf("%s", input);fflush(stdin); 
      if (checkdigit(input)) { 
       input1 = atoi(input); 
      } 
     } while (!checkdigit(input)); 

     switch (input1) { 
     case 1: 
      int c; 
      char encrypted[100]; 
      char word[100]; 
      printf("input word to encrypt : "); 
      scanf(" %[^\n]", word);fflush(stdin); 


      for (int i = 0;i < strlen(word);i++) { 

       if (word[i] == ' ') { 
        encrypted[i] = ' '; 
        //i++; 
       } 
       else { 
        for (int j = 1;j < 27;j++) { 
         if (word[i] == alphabet[j]) { 
          c = 0; 
          c = pow(j, x); 
          c = c%n; 
          encrypted[i] = c; 
          break; 
         } 
        } 
       } 
      } 
      printf("\n\nWord ASCII  [ "); 
      for (int i = 0;i < strlen(word);i++) { 
       //printf("%d", c); 
       printf("%d ", word[i]); 
      } 
      printf(" ]\n"); 


      printf("\n\nEncrypted ASCII  [ "); 
      for (int i = 0;i < strlen(word);i++) { 
       //printf("%d", c); 
       printf("%d ", encrypted[i]); 
      } 
      printf(" ]\n"); 
      printf("\n\nEncrypted  [ "); 
      for (int i = 0;i < strlen(word);i++) { 
       //printf("%d", c); 
       printf("%c", encrypted[i]); 
      } 
      printf(" ]"); 
      printf("\n\n\n"); 
      system("pause"); 
      break; 
     case 2: 
      int temp[100]; 
      char decrypted[100]; 
      char wordx[100]; 
      int h; 
      printf("input word to decrypt : "); 
      scanf(" %[^\n]", wordx);fflush(stdin); 
      for (int i = 0;i < strlen(wordx);i++) { 
       temp[i] = wordx[i]; 
       //temp[i] -= 97; 
       //printf("%d ::: %c\n", temp[i], temp[i]); 
      } 
      for (int i = 0;i < strlen(wordx);i++) { 
       if (wordx[i] == ' ') { 
        decrypted[i] = ' '; 
       } 
       else { 
        h = 0; 
        h = pow(temp[i], y); 
        h = h%n; 
        decrypted[i] = h; 
        for (int j = 1;j < 27;j++) { 
         if (decrypted[i] == j) { 
          decrypted[i] = alphabet[j]; 
         } 
        } 
       } 
      } 
      printf("\n\nWord ASCII  [ "); 
      for (int i = 0;i < strlen(wordx);i++) { 
       //printf("%d", c); 
       printf("%d ", wordx[i]); 
      } 
      printf(" ]\n"); 
      printf("\n\nDecrypted ASCII  [ "); 
      for (int i = 0;i < strlen(wordx);i++) { 
       //printf("%d", c); 
       printf("%d ", decrypted[i]); 
      } 
      printf(" ]\n"); 
      printf("\n\nDecrypted  [ "); 
      for (int i = 0;i < strlen(wordx);i++) { 
       //printf("%d", decrypted[i]); 
       printf("%c", decrypted[i]); 
      } 
      printf(" ]"); 
      printf("\n\n\n"); 
      system("pause"); 
      break; 
     } 
    } while (input1 != 3); 
} 
//===================================================// 
int fpb(int num) { 
    if (!primecheck(num)) { 
     if (num%divider == 0) { 
      num = num/divider; 
      divider = 2; 
     } 
     else { 
      divider++; 
     } 
     fpb(num); 
    } 
    else if (primecheck(num)) { 
     if (!primecheck(num + divider)) { 
      tempdivider++; 
      divider = tempdivider; 
      num = initial; 
      fpb(num); 
     } 
     else { 
      return num + divider; 
     } 
    } 
} 
int d(int num) { 
    for (int i = 1;i < num;i++) { 
     if ((x*i) % num == 1) { 
      return i; 
     } 
    } 

} 

回答

0

的加密選項這三個語句連續

c = 0; 
c = pow(j, x); 
c = c%n; 

最後那些將在範圍0..(n-1)離開c

除此之外,沒有else子句和int c;可以保留未初始化

因此,總而言之,當您將c值打印爲字符時,您將會得到「奇怪」的結果,這是不可避免的。

至於負值,char encrypted[100];大概signed char所以在分配給該範圍內的128..255的任何整數值,雖然未定義的行爲,可能爲負數顯示出來,因爲當作爲通過signed char被促進回int格式%dprintf

1

你有一個普遍的理解問題。您的控制檯只能正確表示96個字符(稱爲可打印的7位ASCII字符,0x20至0x7F),但一個字節可以保存255個不同的值。您的加密算法不關心這個有限的範圍,它會將[0..255]範圍內的任何值加密到[0..255]範圍內的另一個值。所以你的ASCII輸入字符很可能被加密成你的控制檯無法正確表示的值。複製&過去將無法正確工作的非可打印字符(如0x0B,這是一個選項卡)。

但現在你會想:爲什麼這個工作適用於例如電子郵件?簡單地說:因爲這些字符被轉換成ASCII表示。請爲谷歌一點Base64編碼。

作爲一種替代方法,您始終可以將加密字符串流到文件中,然後再從中讀回。這樣你就可以繞過你的控制檯的限制。

順便說一句:請看看printf()的文檔,你會知道,爲什麼你會得到這些負值。