我的任务(不是家庭作业,只是“尝试你能做到这一点”的事情)是使用位操作来加密和解密.txt文件 .
这是该计划 . 它成功打开了读/写文件,但将所有0和空格放入output.txt文件而不是预期的“加密”文本 . 我猜这个问题来自对数据类型或putc()的基本误解 . 我知道它输出一个unsigned char,但是我的教授说无符号字符只是一个无符号整数 - 不确定这是纯粹的真实还是教学简化 . 非常感谢您的帮助 .
#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 回答
你的主要问题是
&=
是一个有损变换:那就是你丢失了数据 .同上
<<=
和>>=
,因为两者都会导致极端1位丢失 .你'll have more luck sticking to XOR; at first at least. That'因为
x ^ y ^ y
是x
.你可以消除
putc
&c . 通过将加密/解密过程与数据采集阶段隔离开来,并通过在输入工作时对输入进行硬编码 .