如何用C语言实现凯撒密码对文本文件(.txt)的读取穷举暴力破解?

用C语言实现对文本文件中凯撒密码穷举破解 并把26次结果 输出为二十六个文本文件(.txt)

 将输入数据放于"read.txt"文件中,编译运行程序即可。

#include<stdio.h>

int main(void){
	FILE *fp=NULL;
	char c[200000],x;
	int i=0,n=0,j=0;
	
	fp=fopen("read.txt","r"); //读取txt文件数据 
	while((x=fgetc(fp))!=EOF){
		c[i]=x;
		i++;
	}
	n=i;
	c[n]='\0';
	fclose(fp);
	
	char f[20]="write00.txt";
	for(i=1;i<=26;i++){
		if(f[6]=='9'){  //将输出文件从01至26排序 
			f[6]='0';
			f[5]++;
		}
		else
			f[6]++;
	
		for(j=0;j<n;j++){  //进行暴力破解,一次将所有字母往后移动一位 
			if(c[j]>='a'&&c[j]<'z')
				c[j]+=1;
			else if(c[j]=='z')
				c[j]='a';
			if(c[j]>='A'&&c[j]<'Z')
				c[j]+=1;
			else if(c[j]=='Z')
				c[j]='A';
		}
		
		fp=fopen(f,"w");//输出文件 
		fputs(c,fp);
		fclose(fp);
	}
	return 0;
}

 

 

凯撒密码即字母替换加密,很常见的一种加密方法。实现分三部分,体现为三个函数:

  • read_file_content 读入输入文件的内容到字符串
  • write_result 将解密结果写入文件
  • decipher 根据特定的偏移量进行解密

decipher函数针对大小写字母进行处理,其他字母保持不变,针对特定的偏移量offset,计算解密后的字母即

// 小写字母
output[i] = ((input[i] - 'a' - offset + 26) % 26) + 'a';
// 大写字母
output[i] = ((input[i] - 'A' - offset + 26) % 26) + 'A';
// 其他字母保持不变
output[i] = input[i];

完整代码如下:

/* File Name: decipher_caesar.c
 * 使用凯撒密码暴力解码文本文件
 * 仅支持英文输入
 */

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


/* Read content from text file named `pathname`*/
size_t read_file_content(const char* pathname, char** buffer, size_t cap) {
    FILE *fptr;
if ((fptr = fopen(pathname, "rb")) == NULL) {
        printf("Error: cannot open file");

        // Exit if failed to open file
        exit(1);
    }
    // obtain file size
    fseek(fptr, 0, SEEK_END);
    long lSize = ftell(fptr);
    rewind(fptr);
    printf("File size: %ld\n", lSize);

    if (cap < lSize) {
        // allocate new memory
        if (*buffer) free(*buffer);

        *buffer = (char*) malloc(sizeof(char) * (lSize + 1));
        if (*buffer == NULL) {
            printf("Memory Error");
            exit(2);
        }
    }

    size_t ret = fread(*buffer, 1, lSize, fptr);
    if (ret != lSize) {
        printf("Reading Error");
        exit(3);
    }

    // terminate
    fclose(fptr);

    return lSize;
}


/* Write content to file named `pathname` */
int write_result(const char* pathname, const char* content, size_t len) {
    FILE *fptr;

    fptr = fopen(pathname, "wb");
    if (fptr == NULL) {
        printf("Error: cannot open file");

        exit(1);
    }

    fwrite(content, sizeof(char), strlen(content), fptr);
    fclose(fptr);

    return 0;
}

/* Decipher using Caesar cipher*/
void decipher(const char* input, char* output, size_t len, int offset) {
    for (size_t i = 0; i < len; i++) {
        if (input[i] > 'a' && input[i] < 'z') {
            output[i] = ((input[i] - 'a' - offset + 26) % 26) + 'a';
        } else if (input[i] > 'A' && input[i] < 'Z') {
            output[i] = ((input[i] - 'A' - offset + 26) % 26) + 'A';
        } else {
            output[i] = input[i];
        }
    }
}

int main() {
    const char* pathname = "input.txt";
    size_t cap = 1024;
    char* content = (char*) malloc (sizeof(char) * cap);
    size_t new_cap = read_file_content(pathname, &content, cap);


    char* output = (char*) malloc (sizeof(char) * (new_cap + 1));
    if (output == NULL) {
        printf("Memory Error");
        exit(2);
    }

    // work through all offsets
    char output_pathname[100];
    for (int i = 0; i < 26; i++) {
        decipher(content, output, new_cap, i);

        // write result
        sprintf(output_pathname, "output_%d.txt", i);
        printf("Writing into %s\n", output_pathname);
        write_result(output_pathname, output, new_cap);
    }

    return 0;
}