我是 C 新手,习惯于 python。但是由于当前世界的情况,我的主计算机被毁坏了,我只剩下 12 年的笔记本电脑。Python 在那里不能很好地工作。
我的目标是创建加密算法。 目前它相当简单,但我稍后会升级它
如何分块读取文件并覆盖其数据?这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
void printa(byte a[]) {
printf("[");
for (int i = 0; i < strlen(a); i++) {
printf("%d", a[i]);
if (i != strlen(a) - 1) {
printf(", ");
};
};
printf("]\n");
};
int encrypt(byte data[], byte key[], int keyi) {
for (int i = 0; i < strlen(data); i++) {
data[i] += key[keyi];
keyi = (keyi + 1) * (keyi < strlen(key) - 1); //branchless if (keyi<strlen(key)) {keyi++;} else {keyi=0;};
};
return keyi;
};
void encrypt_file(byte filename[], byte key[], int buffer_size) {
FILE *file;
byte *buff = calloc(sizeof(byte), buffer_size);
file = fopen(filename, "rb");
if (file == NULL) {
printf("UNABLE TO OPEN FILE\n");
};
};
int main() {
encrypt_file("test.txt", "key", 1024);
return 0;
};
我的文件大小约为 2GB,但我的笔记本电脑内存为 512MB,所以我必须使用分块。
要以块为单位加密文件,您应该使用fread
和fwrite
。
keyi
要在键的末尾重置键索引,将其与 进行比较strlen(key) - 1
可能非常低效,因为strlen()
迭代整个字符串以定位空终止符。只需测试是否key[keyi]
为空字节。
也不必担心无分支代码:
if (key[keyi] == '\0') keyi = 0;
这是修改后的版本:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char byte;
int encrypt(byte data[], size_t size, const byte key[], int keyi) {
for (size_t i = 0; i < size; i++) {
data[i] ^= key[keyi++]; // involutory encryption (apply twice to decrypt)
if (key[keyi] == '\0')
keyi = 0;
}
return keyi;
}
int encrypt_file(const char *filename, const char *filename2,
const byte key[], size_t buffer_size)
{
byte *buff = calloc(sizeof(*buff), buffer_size);
if (buff == NULL) {
fprintf(stderr, "Cannot allocate memory\n");
return 1;
}
FILE *f1 = fopen(filename, "rb");
if (f1 == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", filename, strerror(errno));
free(buff);
return 1;
}
FILE *f2 = fopen(filename2, "wb");
if (f2 == NULL) {
fprintf(stderr, "Cannot open file %s: %s\n", filename2, strerror(errno));
fclose(f1);
free(buff);
return 1;
}
size_t nread;
int keyi = 0;
while ((nread = fread(buff, sizeof(*buff), size, f1)) != 0) {
keyi = encrypt(buff, nread, key, keyi);
if (fwrite(buff, sizeof(*buff), nread, f2) != nread) {
fprintf(stderr, "Error writing to file %s: %s\n", filename2, strerror(errno));
break;
}
}
fclose(f1);
fclose(f2);
free(buff);
return 0;
}
int main() {
return encrypt_file("test.txt", "test.out", (const byte *)"key", 1024);
}
您可以修改程序以就地加密文件,但请注意,如果进程中断,部分加密的文件将难以恢复。您还应该尝试保留文件修改时间。一种更安全的方法是使用适当的工具对分区进行加密,其中一些工具支持隐藏分区和合理的可否认性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句