2017-01-07 5 views
-2

У меня возникли проблемы с выполнением моей домашней работы.
Я делаю приложение RSA, которое может шифровать и расшифровывать.RSA Encryption C code

Проблема в том, что после ввода данных для шифрования результатов странно, и я не могу расшифровать что-либо. Это связано с тем, что, когда я копировал результаты шифрования, которые являются символами, я получил более странные вещи.

Я предполагаю, что это имеет какое-то отношение к моей формуле, получающей отрицательные 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; 

и последний из тех, кто оставит c в диапазоне 0..(n-1).

Кроме того, нет else положения и int c; может оставаться неиницализированные.

Так что все это неизбежно, когда вы печатаете c значениями в качестве символов, вы получите «странные» результаты.

Что касается отрицательных значений, char encrypted[100];, вероятно, signed char так что любое целое значение в диапазоне 128..255 присвоенного, что, хотя неопределенное поведение, возможно показать в виде отрицательного числа, так как signed char способствует обратно int, когда передается как формат %d - printf.

1

У вас есть общая проблема понимания. Ваша консоль может отображать только 96 символов (известные как печатные 7bit-ASCII-символы, от 0x20 до 0x7F), но байт может содержать 255 различных значений. Ваш алгоритм шифрования не заботится об этом ограниченном диапазоне, он зашифрует любое значение в диапазоне [0..255] в другое значение в диапазоне [0..255]. Таким образом, ваши входные символы ASCII, скорее всего, будут зашифрованы в значения, которые не могут быть представлены вашей консоль правильно. Копировать & Прошлое не будет работать правильно для непечатаемых символов (например, 0x0B, это вкладка).

Но теперь вы задаетесь вопросом: почему это работает, например? E-Mail? Просто: потому что эти символы преобразуются в представление ASCII. Пожалуйста, google немного для кодировки Base64.

В качестве альтернативы вы всегда можете передавать ваши зашифрованные символы в файл и позже читать обратно. Таким образом вы обойдете ограничения своей консоли.

КПП: Пожалуйста, ознакомьтесь с документацией printf(), и вы узнаете, почему вы получаете эти отрицательные значения.