The idea originally was to have a number of files in a folder and after the encryption, to add "_encryption" to the name, making it like a first barrier for the people who do not understand from tech at all, as they wont be able to read the file, when they don't know the extension. Also I have to check what will happen if the extension is hidden by the OS.
The problem comes from the strcat() and strcpy() functions. When I use "scanf()" everything is ok, but otherwise no.
I have 2 versions now.
Version1:
Code:
/*
The example is working. Implementing a simple encryption method. The professor told me that this is the encryption banks use with a longer public key (??? publicly known how long it is). In the example that he gave though, we were allocating memory with "malloc()" or "calloc()" (I thinkg it was "calloc()". He was indexing both the file and the key with a counter (i,z), I think the same counter for the file and key (i for the the file and key)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <conio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// declare function before it's called
void Encrypt(char * FILENAME, char * NEW_FILENAME, char * process);
int is_regular_file(const char *path);
char *strremove(char *str, const char *sub);
int NotExe (char * f1);
int StringFind(char str[], char search[]);
int main ()
{
char f1[256]; // array big enough to hold expected input, max in Windows is 256 chars with the path
char f2[256]; // array big enough to hold expected input, max in Windows is 256 chars with the path
char process[50]; // array big enough to hold expected input
char Decryption[50] = "Decryption_";
char Encryption[50] = "Encryption_";
DIR *d;
struct dirent *dir;
/* This block inputs file names from the user
printf ("Please enter file for encryption\n");
scanf ("%99s", f1); // set max characters to read to prevent buffer overflow
printf ("Please enter the name of the file after encryption\n");
scanf ("%99s", f2);
*/
START:
printf ("Please enter 'encryption or decryption'\n");
scanf ("%49s", process);
d = opendir("."); // Open the directory
if (d) // If the directory is not empty "if (d) != 0"
{
while ((dir = readdir(d)) != NULL) // While the directory is not empty
{
if (is_regular_file(dir->d_name)) // If the file is not a directory
{
strcpy(f1, (dir->d_name)); // Transfer the file name into f1 to avoid "Can't open inFile"
// strcpy(f2, "encryption_"); // Transfer the file name into f1 to avoid "Can't open inFile"
if (NotExe (f1) == 0) // If the file is not an .exe
{
if (strcmp (process, "decryption")) // If the process is "decryption"
{
if (StringFind(f1, Encryption) == 0) // If the substring is found
{
strremove(f1, Encryption); // Remove the substring
strcpy (f2, Decryption); // Transfer the file name into f2 to avoid "Can't open inFile"
strcat (f2, f1); // Add to the file name "Decryption_" + "FileName"
printf ("\nf2 = %s\n", f2); // For debugging only
}
}
else if (StringFind(f1, Encryption) != 0) // If the substring is not found and the process is "encryption"
{
//printf ("else if = %d", strstr(f1, Encryption));
//strcpy(f2, f1); strcat(f2, "_"); strcat(f2, process);
strcpy (f2, Encryption); // Transfer the file name "Encryption_" into f2 to avoid "Can't open inFile"
strcat (f2, f1); // Transfer the file name into f2
printf ("\noutFile f2 = %s\n", f2); // For debugging only
}
Encrypt(f1, f2, process);
}
}
}
closedir(d); // Close the directory
goto START;
return 1; // The software did not return to START
}
}
void Encrypt(char * FILENAME, char * NEW_FILENAME, char * process)
{
printf("Process started\n");
FILE *inFile;
FILE *outFile;
char key[256] = "EyBtLfnPP9htzwXHjayXeuFV3TDdiSFjESL3K3do4E1HQqru1w0UTBhuotsQ9PVCup6mwB9hhrU11aroOJMlw1xYQ5PhfLIMp5WDzr3gXrERuIADifqGDQ6LyyDAsKqI9P7iVDNsMTBYzHENdcXpP1aCdmSgEqfuOkGHnhP0LxcsusIFGIYLACU3TYKDmwWEEs99Jc0mcZeXA8P4VGEIL4qIqauL0twT9H3koBq1jfDXe8SiekYGGVRg87uuTtIl"; // array big enough to hold expected input, dont give "char *" to scanf with "%s"
int keylen, keyidx;
int Byte; // fgetc returns int, so use an int for "Byte" and "newByte"
int newByte;
//printf ("Please enter the key\n");
//scanf ("%49s", key);
keylen = strlen(key);
keyidx = 0; // starting index into key
printf("Opening files\n");
inFile = fopen(FILENAME,"rb");
outFile = fopen(NEW_FILENAME, "w");
if(inFile == NULL)
{
printf("Error: Can't Open inFile\n");
}
else if(outFile == NULL)
{
printf("Error: Can't open outFile\n");
}
else
{
printf("File Opened, processing\n");
while((Byte = fgetc(inFile)) != EOF) // read a byte, check if EOF, "EOF" is outside the range of "char most times"
{
if (!strcmp(process,"encryption")) /* ??? "strmcp()" compares (process) a string to(encryption) a string */
{
newByte = Byte + key[keyidx]; // use key index
if (newByte > 255) newByte -= 256; // check for overflow
}
else if (!strcmp(process,"decryption"))
{
newByte = Byte - key[keyidx];
if (newByte < 0) newByte += 256;
}
else
{
newByte = Byte;
}
fputc(newByte, outFile);
keyidx++;
// loop to the start of the key if needed
if (keyidx >= keylen) keyidx = 0;
}
}
if (inFile != NULL) fclose(inFile); // close your files when you're done
if (outFile != NULL) fclose(outFile);
}
// Check if a file is a directory, the check must be update
// to include checks for other not used files, like pipes and etc.
int is_regular_file(const char *path)
{
struct stat path_stat;
stat(path, &path_stat);
return S_ISREG(path_stat.st_mode);
}
char *strremove(char *str, const char *sub)
{
size_t len = strlen(sub);
if (len > 0) {
char *p = str;
while ((p = strstr(p, sub)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
int NotExe (char * f1)
{
if (strstr(f1, ".exe"))
{
return 1;
}
else
{
return 0;
}
}
int StringFind(char str[], char search[])
{
//char str[] = "teacher teach tea";
//char search[] = "ac";
char *ptr = strstr(str, search);
if (ptr != NULL) /* Substring found */
{
printf("'%s' contains '%s'\n", str, search);
return 0;
}
else /* Substring not found */
{
printf("'%s' doesn't contain '%s'\n", str, search);
return 1;
}
}
Version 2:
Code:
/* Usage
$ gcc encryptor.c -o encryptor
$ ./encryptor /path/to/folder encrypt
$ ./encryptor /path/to/folder decrypt
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define KEY 'K' // Change this to any other character for a different key
void encryptFile(char *filename) {
FILE *fp;
char ch;
fp = fopen(filename, "rb+");
if (fp == NULL) {
printf("\nCannot open file: %s", filename);
return;
}
while ((ch = fgetc(fp)) != EOF) {
ch = ch ^ KEY;
fseek(fp, -1L, SEEK_CUR);
fputc(ch, fp);
}
fclose(fp);
}
void decryptFile(char *filename) {
encryptFile(filename); // XOR encryption and decryption are the same operation
}
int main(int argc, char *argv[]) {
char *folderPath, *command;
size_t pathLength;
if (argc != 3) {
printf("Usage: %s <folder_path> <encrypt/decrypt>\n", argv[0]);
return 1;
}
folderPath = argv[1];
pathLength = strlen(folderPath);
if (folderPath[pathLength-1] != '/') {
folderPath = realloc(folderPath, pathLength + 2);
folderPath[pathLength] = '/';
folderPath[pathLength+1] = '\0';
}
command = argv[2];
if (strcmp(command, "encrypt") == 0) {
printf("Encrypting files in folder: %s\n", folderPath);
char *commandBuffer = malloc(pathLength + 30);
sprintf(commandBuffer, "find %s -type f -exec %s {} \\;", folderPath, argv[0]);
system(commandBuffer);
free(commandBuffer);
printf("Done.\n");
} else if (strcmp(command, "decrypt") == 0) {
printf("Decrypting files in folder: %s\n", folderPath);
char *commandBuffer = malloc(pathLength + 30);
sprintf(commandBuffer, "find %s -type f -exec %s {} \\;", folderPath, argv[0]);
system(commandBuffer);
free(commandBuffer);
printf("Done.\n");
} else {
printf("Invalid command: %s\n", command);
return 1;
}
return 0;
}
On version 2, I get "encryptor has stopped responding, do you want to close the window".