c - 手册 "encryption"只输出0到文件

标签 c file file-io bitwise-operators

我的作业(不是家庭作业,只是“如果你能做到就试试”的事情)是使用位操作来加密和解密 .txt 文件。

这是程序。它成功打开文件进行读/写,但将所有 0 和空格放入 output.txt 文件而不是预期的“加密”文本。我猜这个问题来自于对数据类型或 putc() 的根本误解。我知道它输出一个 unsigned char,但我的教授说 unsigned char 只不过是一个 unsigned int——不确定这是否完全正确,或者它是否是一种教学简化。非常感谢您的帮助。

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

#define NUMARG 3
#define INFILEARG 1
#define OUTFILEARG 2

int main(int argc, char *argv[]){
    /* Function prototypes */
    unsigned int encryptDecrypt(unsigned int x, unsigned int ed);
    const char *get_filename_ext(const char *filename);

    FILE *finp;
    FILE *foutp;

    //ed for encryption/decryption choice
    unsigned int ed, c;
    const char *ext;

    //Check for errors in argument number and file opening.
    if(argc != NUMARG){
        printf("You have to put the input and output files after the 
                program name.\n");
        return(1);
    }

    if( (finp = fopen(argv[INFILEARG], "r")) == NULL ){
         printf("Couldn't open %s for reading.\n", argv[INFILEARG]);
         return(1);
    }

    if( (foutp = fopen(argv[OUTFILEARG], "w")) == NULL){
        printf("Couldn't open %s for writing.\n", argv[OUTFILEARG]);
        return(1);
    }


    //Get and check file extension.
    ext = get_filename_ext(argv[INFILEARG]);
    if(strcmp(ext, "txt")){
        printf("Input file is not a .txt file.\n");
        return(1);
    }

    ext = get_filename_ext(argv[OUTFILEARG]);
    if(strcmp(ext, "txt")){
        printf("Output file is not a .txt file.\n");
        return(1);
    }

    //Get command to encrypt or decrypt.
    do{
        printf("Enter e to encrypt, d to decrypt: ");
        ed = getchar();
    } while(ed != 'e' && ed != 'd');


    //Send characters to output file.
    while((c = getc(finp)) != EOF ){
         putc(encryptDecrypt(c, ed), foutp);
    }


    // Close files.
    if (fclose(finp) == EOF){
         printf("Error closing input file.\n");
    }

    if (fclose(foutp) == EOF){
        printf("Error closing output file.\n");
    }

    if ( ed == 'e'){
        printf("Encrypted data written.\n");
    } else {
         printf("Data decrypted.\n");
    }

    return 0;
}

const char *get_filename_ext(const char *filename) {
    const char *dot = strrchr(filename, '.');
    if(!dot || dot == filename) return "";
    return dot + 1;
}

unsigned int encryptDecrypt(unsigned int c, unsigned int ed){
    if( ed == 'e' ){
        printf("%d before operated on.\n", c);
        c &= 134;
        printf("%d after &134.\n", c);
        c ^= 6;
        printf("%d after ^6. \n", c);
        c <<= 3; 
        printf("%d after <<3\n", c);
    }
    else {
        c >>= 3;
        c ^= 6;
        c &= 134;       
    }   
    return c;
}

输出:

ZacBook:bitoperations $ cat input1.txt
Please encrypt this message.
ZacBook:bitoperations $ ./encrypt.o input1.txt output.txt
Enter e to encrypt, d to decrypt: e
80 before operated on.
0 after &134.
6 after ^6. 
48 after <<3
108 before operated on.
4 after &134.
2 after ^6. 
16 after <<3
[...Many more of these debug lines]
2 after &134.
4 after ^6. 
32 after <<3
Encrypted data written.
ZacBook:bitoperations $ cat output.txt
00 0  00000 0  0 

如您所见,unsigned int 正在成功运行。我认为问题出在 putc() 上,但我已尝试将 c 的类型更改为 char 和 int,但均无效。

最佳答案

你的主要问题是&=是一个有损转换:也就是说你丢失了数据。

同上<<=>>= ,因为两者都会导致极端 1 位丢失。

坚持异或你会更幸运;起初至少。那是因为 x ^ y ^ yx .

你可以消除putc &C。通过将加密/解密过程与数据采集阶段隔离开来,并在让事情正常运行的同时对输入进行硬编码。

关于c - 手册 "encryption"只输出0到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46673754/

相关文章:

java - 如何扫描图像文件夹并将其添加到图像数组

c - 函数内存分配问题

c - 指针变量的大小存储在哪里?

通过宏创建数组

c - 在 while 循环中等待在 C 中按 Enter 键?

javascript - 如何从 window.location.pathname 获取文件名

file - 如何使用反斜杠符号和 2 个点 ('\..' 获取文件路径

java - 存储、检索、编辑和删除数据

c# - DirectoryExists ("c:temp\\foo") 当目录不存在时返回真!

c++ - 为什么在第三个文件之前写入两个文件,即使指令是每次迭代都执行一个文件?