Single table substitution cipher

Caesar cipher

Caser encrypted password is a classic, invented by Julius Caser, when the invention is that the 26 letters in alphabetical cyclic shift, according to the order a -> d, b -> e, c -> f. ..... The shift different collectively referred to as shift cipher.

According to quintuple cryptosystem

A = {P, B, C ...... Z}
C = {A, B, C ...... Z}
K = 0,1,2 ...... {25}
if Caser password, to obtain the encryption algorithm
E P = (P +. 3) MOD 26 is
when the shift may be any integer, to obtain an encryption algorithm
E P = (K + P) MOD 26 is
obtained decryption algorithm
D C = (C - K) MOD 26 is
injection : mod modulo arithmetic that is to take over
as the key space may only have 26 kinds, and up to 25 kinds of test that is able to obtain k, using brute-force attack is very easy to achieve.

Single table substitution cipher

If the shift key space allows arbitrary password in place, it can be obtained 26! Possible key, as a single table instead of a password, a sharp increase in the key space, can resist brute-force attack, but due to some statistical laws of language use can still hack attack.

Letter frequency analysis to decrypt

In English, for example, is first necessary to use all the letters of the alphabet relative frequency figured out, and a given ciphertext letter frequencies are compared, but this method requires long enough to ensure that the ciphertext is known, and in some approximate frequency between letters the need for human analysis.
Alternatively alphabet letters known form five higher frequency of occurrence e, t, a, o, i.

C language

  • Function:
    • Command input error checking
    • Achieve encryption and decryption of all files
    • Achieve translocation password decryption key is known, the case-sensitive, non-alphabetic next ciphertext reserved
    • Increase the shift cipher key using an unknown letter frequency analysis to decrypt
  • Implementation environment:
    • Operating System: Windows10
    • Compiler environment: Code :: Blocks
  • Screenshot realization:
    avatar
  • Areas for improvement:
    mainly in terms of the unknown key to decrypt encrypted with any single table if the alternative method, it is decrypted using letter frequency analysis requires human intervention, it is only for the convenience of using a frequency shift cipher letter writing program analysis made simple decryption. In case not enough is known ciphertext, the frequency of the letters may appear similar or identical, it is possible to take a high frequency of occurrence of the top three to display artificial selection, in order to facilitate this feature is also not implemented.

  • Implementation code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void Encrypt(int key, char infilename[], char outfilename[]);//加密函数
void Decrypt(int key, char infilename[], char outfilename[]);//解密函数
void frequency(char infilename[], char outfilename[]);//频率分析解密函数
int Character(char);//字符判断函数

int main(int argc, char *argv[]){
    if (argc != 5 || argv[1][0] != '-' || argv[1][2] != '\0'){
        printf("Usage: exename -e/-d key inputfile outputfile\nno key Usage: exename -d no inputfile outputfile");
        return;
    }
    int key = atoi(argv[2]);//密钥
    if (key == 0 ){
        if(argv[1][1] != 'd'){
            printf("Usage: exename -e/-d key inputfile outputfile\nno key Usage: exename -d no inputfile outputfile");
        }else{
            frequency(argv[3], argv[4]);
        }
    }else{
        if (key <0 || key >25) { //判断密钥合法性
            printf("The key is wrong!\n");
            return;
        }
        switch (argv[1][1]){
            case 'e':
                Encrypt(key, argv[3], argv[4]);
                break;
            case 'd':
                Decrypt(key, argv[3], argv[4]);
                break;
            default:
                break;
        }
    }
    return;
}

void Encrypt(int key, char infilename[], char outfilename[]){
    char plaintext[1000] = { 0 };//定义明文数组
    FILE *fp = NULL;//定义文件指针
    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(infilename, "r");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(plaintext, 999, fp);
    }else{//非文本文件
        fp = fopen(infilename, "rb");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(plaintext, 999, fp);//读取文件中的明文存放到数组中
    }
    fclose(fp);
    int pl = strlen(plaintext);//明文长度

    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(outfilename, "w");
    }else{//非文本文件
        fp = fopen(outfilename, "wb");
    }
    int i,value;
    for (i = 0; i < pl; i++){
        value = Character(plaintext[i]);
        if (value == -1) fprintf(fp, "%c", (plaintext[i] - 'a' + key) % 26 + 'a');
        if (value == 1)  fprintf(fp, "%c", (plaintext[i] - 'A' + key) % 26 + 'A');
        if (value == 0 || value == 255) fprintf(fp, "%c", plaintext[i]);
    }//通过移位加密原理输出密文
    fclose(fp);
    printf("The file is encrypt successful.\n");
}

void Decrypt(int key, char infilename[], char outfilename[]){
    char ciphertext[1000] = { 0 };//定义密文
    FILE *fp = NULL;//定义文件指针
    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(infilename, "r");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(ciphertext, 999, fp);
    }
    else{//非文本文件
        fp = fopen(infilename, "rb");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(ciphertext, 999, fp);
    }
    fclose(fp);
    int cl = strlen(ciphertext);//密文长度

    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(outfilename, "w");
    }
    else{//非文本文件
        fp = fopen(outfilename, "wb");
    }
    int i,value;
    for (i = 0; i < cl; i++){
        value = Character(ciphertext[i]);
        if (value == -1)fprintf(fp, "%c", (ciphertext[i] - 'a' - key + 26) % 26 + 'a');
        if (value == 1) fprintf(fp, "%c", (ciphertext[i] - 'A' - key + 26) % 26 + 'A');
        if (value == 0 || value == 255) fprintf(fp, "%c", ciphertext[i]);
    }//通过移位解密原理输出明文
    fclose(fp);
    printf("The file is decrypt successful.\n");
}

void frequency(char infilename[], char outfilename[]){
    char ciphertext[1000] = { 0 };//定义密文
    FILE *fp = NULL;//定义文件指针
    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(infilename, "r");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(ciphertext, 999, fp);
    }
    else{//非文本文件
        fp = fopen(infilename, "rb");
        if (fp == NULL) {
            printf("The file was not found!\n");
            return;
        }
        fgets(ciphertext, 999, fp);
    }
    fclose(fp);
    int cl = strlen(ciphertext);//密文长度

    int i, value, a[26] = { 0 };
    for (i = 0; i < cl; i++){
        value = Character(ciphertext[i]);
        if (value == -1) { a[ciphertext[i] - 'a']++; }
        else if (value == 1) { a[ciphertext[i] - 'A']++; }
    }//将每个字母出现的次数存放到a数组中

    int max, e;
    for (i = 0, max = 0; i<26; i++){
        if (a[i] > max) {
            max = a[i];
            e = i;
        }
    }//找到频率最高的字母即为e
    int key = (e + 22) % 26;//求出密钥值

    if (strchr(infilename, '.txt') != NULL){//文本文件
        fp = fopen(outfilename, "w");
    }
    else{//非文本文件
        fp = fopen(outfilename, "wb");
    }
    for (i = 0; i < cl; i++){
        value = Character(ciphertext[i]);
        if (value == -1)fprintf(fp, "%c", (ciphertext[i] - 'a' - key + 26) % 26 + 'a');
        if (value == 1) fprintf(fp, "%c", (ciphertext[i] - 'A' - key + 26) % 26 + 'A');
        if (value == 0 || value == 255) fprintf(fp, "%c", ciphertext[i]);
    }//通过字母频率分析解密原理输出明文
    fclose(fp);
    printf("The file is decrypt successful.\n");

}

int Character(char n){
    if (n >= 'a'&&n <= 'z') {
        return -1;//小写
    }
    else if (n >= 'A'&&n <= 'Z') {
        return 1;//大写
    }
    else if (n == ' '){
        return 0;//空格
    }
    else{
        return 255;//其它字符
    }
}

Guess you like

Origin www.cnblogs.com/saltedcorgi/p/12034449.html