C#

Cript (шифрование файлов)

С твоего кода даже обфускатор офигеет. (С) _не_помню_кто_сказал_


Сначала у меня была идея побаловаться с ООП на Си. И я решил сделать небольшую программку для шифрования файлов. Ниже привожу сорцы.

typedefs.h - В файле основные дефайны, инклуды и макрос __PRINT_DBG(), который я использовал для дебага. Этот файл подключается ко всем остальным файлам.
#ifndef TYPEDEFS_H_INCLUDED
#define TYPEDEFS_H_INCLUDED

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

#if SYSTEM == MSDOS
	#define WIN_OS
#elif SYSTEM == LINUX
	#define LIN_OS
#endif

#define DEBUG_MOD
#undef DEBUG_MOD

#ifdef DEBUG_MOD
	#define __PRINT_DBG( x )\
		printf ( (x) )
#else
	#define __PRINT_DBG(x)\
		printf ("")
#endif

#define NOOB_CRIPT_ALGORITHM 0
typedef int bool;
enum BOOL {FALSE, TRUE};
#define class typedef struct
#define sub  void

#endif



Дальше идет код, отвечающий за хранение и изменение настроек. Может это не очень хорошая идея, но я ничего другого не придумал.
settings_class.h
#ifndef SETTINGS_CLASS_H_INCLUDED
#define SETTINGS_CLASS_H_INCLUDED



class {
// public:
//	Settings();

//	bool isRemove();
//	bool isSettingTypeOfCript();
//	int  getCriptAlgorithm();
//	int  getCriptBufSize();
//	FILE *getInputFile();
//	FILE *getOutputFile();

//	void setCript (bool val);
//	void setRemove (bool val);
//	void setSettingsTypeOfCript (bool val);
//	void setCriptAlgorithm (int val);
//	void setCriptBufSize (int val);
//	void setInputFile (FILE *inputfile);
//	void setOutputFile (FILE *outputfile);

//	~Settings();

// private:
	bool remove;
	bool reverse;
	int  criptAlgorithm;
	int criptBufSize;
	bool settedInputFile;
	char* inputfilename;
	FILE *inputfile;
	bool settedOutputFile;
	char* outputfilename;
	FILE *outputfile;
} Settings;

#endif


settings.h
#ifndef SETTINGS_H_INCLUDED
#define SETTINGS_H_INCLUDED



#include "typedefs.h"
#include "settings_class.h"


sub Settings_constructor (Settings *this);

bool Settings_isRemove (Settings *this);
bool Settings_isReverse (Settings *this);
int Settings_getCriptAlgorithm (Settings *this);
int Settings_getCriptBufSize (Settings *this);
bool Settings_isSettedInputFile (Settings *this);
char* Settings_getInputFileName (Settings *this);
FILE *Settings_getInputFile (Settings *this);
bool Settings_isSettedOutputFile (Settings *this);
char* Settings_getOutputFileName (Settings *this);
FILE *Settings_getOutputFile (Settings *this);

sub Settings_setRemove (Settings *this, bool val);
sub Settings_setReverse (Settings *this, bool val);
sub Settings_setCriptAlgorithm (Settings *this, int val);
sub Settings_setCriptBufSize (Settings *this, int val);
sub Settings_setSettedInputFile (Settings *this, bool val);
sub Settings_setInputFileName (Settings *this, char* path);
sub Settings_setInputFile (Settings *this, FILE *inputfile);
sub Settings_setSettedOutputFile (Settings *this, bool val);
sub Settings_setOutputFileName (Settings *this, char* path);
sub Settings_setOutputFile (Settings *this, FILE *outputfile);

sub Settings_destructor (Settings *this);

#endif


settings.c
#include "typedefs.h"
#include "settings.h"



sub Settings_constructor (Settings *this) {
	this->remove = FALSE;
	this->reverse = FALSE;
	this->criptAlgorithm = 0;
	this->criptBufSize = 1024 * 1024;
	this->settedInputFile = FALSE;
	this->inputfile = NULL;
	this->inputfilename = NULL;
	this->settedOutputFile = FALSE;
	this->outputfile = NULL;
	this->outputfilename = NULL;
}



bool Settings_isRemove (Settings *this) {
	return this->remove;
}



bool Settings_isReverse (Settings *this) {
	return this->reverse;
}



int Settings_getCriptAlgorithm (Settings *this) {
	return this->criptAlgorithm;
}



int Settings_getCriptBufSize (Settings *this) {
	return this->criptBufSize;
}



bool Settings_isSettedInputFile (Settings *this) {
	return this->settedInputFile;
}



char* Settings_getInputFileName (Settings *this) {
	return this->inputfilename;
}



FILE *Settings_getInputFile (Settings *this) {
	return this->inputfile;
}



bool Settings_isSettedOutputFile (Settings *this) {
	return this->settedOutputFile;
}



char* Settings_getOutputFileName (Settings *this) {
	return this->outputfilename;
}



FILE *Settings_getOutputFile (Settings *this) {
	return this->outputfile;
}



sub Settings_setRemove (Settings *this, bool val) {
	this->remove = val;
}



sub Settings_setReverse (Settings *this, bool val) {
	this->reverse = val;
}



sub Settings_setCriptAlgorithm (Settings *this, int val) {
	this->criptAlgorithm = val;
}




sub Settings_setCriptBufSize (Settings *this, int val) {
	this->criptBufSize = val;
}



sub Settings_setSettedInputFile (Settings *this, bool val) {
	this->settedInputFile = val;
}



sub Settings_setInputFileName (Settings *this, char* path) {
	this->inputfilename = path;
}



sub Settings_setInputFile (Settings *this, FILE *inputfile) {
	this->inputfile = inputfile;
}



sub Settings_setSettedOutputFile (Settings *this, bool val) {
	this->settedOutputFile = val;
}



sub Settings_setOutputFileName (Settings *this, char* path) {
	this->outputfilename = path;
}



sub Settings_setOutputFile (Settings *this, FILE *outputfile) {
	this->outputfile = outputfile;
}



sub Settings_destructor (Settings *this) {
	this->inputfile = NULL;
	this->inputfilename = NULL;
	this->outputfile = NULL;
	this->outputfilename = NULL;
}



Настройки частично могут поменяться, если вызывать программу с параметрами. За их парсинг отвечает следующий код.

arg_class.h
#ifndef ARG_CLASS_H_DEFINED
#define ARG_CLASS_H_DEFINED



class {
// public:
//	void argPars (int argc, char **argv);
//	void srgSet (char *arg);
//	void setTypeOfCript (char *type);
//	void setInputFile (char *path);
//	void setOutputFile (char *path);

// private:
	Settings *setups;
} Arg;



#endif


arg.h
#ifndef ARG_H_INCLUDED
#define ARG_H_INCLUDED



#include "typedefs.h"
#include "arg_class.h"
#include "settings_class.h"



// From 'main.c'.
sub showUsage (void);



sub Arg_constructor (Arg *this, Settings *setups);

sub Arg_argPars (Arg *this, int argc, char **argv);
sub Arg_argSet (Arg *this, char *arg);
sub Arg_flagSet (Arg *this, char *arg);
sub Arg_setTypeOfCript (Arg *this, char *type);
sub Arg_setInputFile (Arg *this, char *path);
sub Arg_setOutputFile (Arg * this, char *path);

sub Arg_destructor (Arg *this);



#endif


arg.c
#include "settings.h"
#include "arg.h"
#include "main.h"



sub Arg_constructor (Arg *this, Settings *setups) {
	__PRINT_DBG("__FUNC: Arg_constructor\n");
	this->setups = setups;
}



sub Arg_argPars (Arg *this, int argc, char **argv) {
	__PRINT_DBG("__FUNC: Arg_argPars\n");
	for (int i = 1; i < argc; i++) {
		       if (argv[i][0] == '-' && argv[i][1] != '-') {
			Arg_argSet (this, argv[i]);
		} else if (argv[i][0] == '-' && argv[i][1] == '-') {
			Arg_flagSet (this, argv[i]);
		} else if (Settings_isSettedInputFile (this->setups) == FALSE) {
			Arg_setInputFile (this, argv[i]);
		} else if (Settings_isSettedOutputFile (this->setups) == FALSE) {
			Arg_setOutputFile (this, argv[i]);
		} else {
			printf ("Invalide argument \'%s\'!\n", argv[i]);
			exit (1);
		}
	}

	if (Settings_getInputFile (this->setups) != NULL && Settings_getOutputFile (this->setups) == NULL) {
		Arg_setOutputFile (this, strcat (Settings_getInputFileName (this->setups), ".cript"));
	}

	if (Settings_getInputFile (this->setups) == NULL) {
		printf ("Missed a input file!\n");
		exit (1);
	}
}



sub Arg_argSet (Arg *this, char *arg) {
	__PRINT_DBG("__FUNC: Arg_argSet\n");
	for (int i = 1; arg[i] != '{EDIT_TEXT}'; i++) {
		#define param arg[i]
		       if (param == 'R') {
			Settings_setReverse (this->setups, 1);
		} else if (param == 'r') {
			Settings_setRemove (this->setups, 1);
		} else {
			printf ("Invalid arguments!\n");
			showUsage();
			exit (1);
		}
		#undef param
	}
}



/* If str1 == str2 then return 1. */
bool Arg_mystrcmp (char* str1, char *str2) {
	while (*str1 == *str2 && *str1 != '=') {
		str1++; str2++;
	}

	if (*str1 == *str2 && *str1 == '=') {
		return 1;
	} else {
		return 0;
	}
}



char *Arg_getParam (char *arg) {
	while (*arg != '=' && *arg != '{EDIT_TEXT}') {
		arg++;
	}
	if (*arg == '=') {
		arg++;
		return arg;
	} else {
		return NULL;
	}
}



sub Arg_flagSet (Arg *this, char *arg) {
	__PRINT_DBG("__FUNC: Arg_flagSet\n");
	char *param;

	       if (Arg_mystrcmp (arg, "--cript-met=")) {
		param = Arg_getParam (arg);

		       if (!strcmp (param, "noob")) {
			/***/printf ("noob\n");
			Settings_setCriptAlgorithm (this->setups, NOOB_CRIPT_ALGORITHM);
		} else {
			printf ("Invalide parametr of \'--cript-met=\'!\n");
			showUsage();
			exit (1);
		}
	} else if (!strcmp (arg, "--reverse")) {
		Settings_setReverse (this->setups, TRUE);
	} else if (!strcmp (arg, "--remove")) {
		Settings_setRemove (this->setups, TRUE);
	} else if (!strcmp (arg, "--help")) {
		showUsage();
	} else {
		printf ("Invalide argument \'%s\'!\n", arg);
		showUsage();
		exit (1);
	}
}



sub Arg_setTypeOfCript (Arg *this, char *type) {
	//
}



sub Arg_setInputFile (Arg *this, char *path) {
	__PRINT_DBG("__FUNC: Arg_setInputFile\n");
	FILE *file;
	if ((file = fopen (path, "rb")) != NULL) {
		Settings_setSettedInputFile (this->setups, TRUE);
		Settings_setInputFileName (this->setups, path);
		Settings_setInputFile (this->setups, file);
	} else {
		printf ("File \'%s\' not exist!\n", path);
		exit (1);
	}
}



sub Arg_setOutputFile (Arg * this, char *path) {
	__PRINT_DBG("__FUNC: Arg_setOutputFile\n");
	FILE *file;

// Cleaning file.
	if ((file = fopen (path, "w")) == NULL) {
		printf ("Can\'t create a file \'%s\'!\n", path);
		exit (1);
	} else {
		fclose (file);
	}

	if ((file = fopen (path, "ab")) != NULL) {
		Settings_setSettedOutputFile (this->setups, TRUE);
		Settings_setOutputFileName (this->setups, path);
		Settings_setOutputFile (this->setups, file);
	} else {
		printf ("Can\'t create a file \'%s\'!\n", path);
		exit (1);
	}
}



sub Arg_destructor (Arg *this) {
	__PRINT_DBG("__FUNC: Arg_destructor\n");
	this->setups = NULL;
}


Возможно, я не правильно понимаю наследование или не правильно его применяю (что, в общем-то, одно и то же), но решил я сделать так.

criptbuf_class.h
#ifndef CRIPTBUF_CLASS_H_INCLUDED
#define CRIPTBUF_CLASS_H_INCLUDED



class {
// public:
//	CriptBuf();
//	~CriptBuf();

// protected:
	char *buf;
} CriptBuf;



#endif


criptbuf.h
#ifndef CRIPT_BUF_H_INCLUDED
#define CRIPT_BUF_H_INCLUDED



#include "typedefs.h"
#include "criptbuf_class.h"



sub CriptBuf_constructor (CriptBuf *this, int bufSize);

char CriptBuf_getBit (CriptBuf *this, int num);
void CriptBuf_setBit (CriptBuf *this, int num, char val);

sub CriptBuf_destructor (CriptBuf *this);



#endif


criptbuf.c
#include "criptbuf.h"



sub CriptBuf_constructor (CriptBuf *this, int bufSize) {
	__PRINT_DBG("__FUNC: CriptBuf_constructor\n");
	this->buf = (char *) calloc (bufSize, sizeof (char));
}



char CriptBuf_getBit (CriptBuf *this, int num) {
	return this->buf[num];
}



void CriptBuf_setBit (CriptBuf *this, int num, char val) {
	this->buf[num] = val;
}



sub CriptBuf_destructor (CriptBuf *this) {
	__PRINT_DBG("__FUNC: CriptBuf_destructor\n");
	free (this->buf);
}



Предыдущий класс "наследуется" следующим (который и отвечает за шифрование).

cript_class.h
#ifndef CRIPT_CLASS_H_INCLUDED
#define CRIPT_CLASS_H_INCLUDED


#include "settings_class.h"
#include "criptbuf_class.h"


class /* protected: CriptBuf, protected: CriptAlgorithm */ {
// public:
//	Cript();
//	void setCriptAlgorithm();
//	void setPreCriptBuf();
//	void writeCript();
//	virtual void doCripting() = 0;
//	~Cript();

// private:
	Settings *setups;

// parents:
	CriptBuf *CriptBuf;
} Cript;



#endif


cript.h
#ifndef CRIPT_H_INCLUDED
#define CRIPT_H_INCLUDED



#include "typedefs.h"
#include "settings.h"
#include "cript_class.h"



sub Cript_constructor (Cript *this, Settings *setups);

sub Cript_setPreCriptBuf (Cript *this);
sub Cript_writeCript (Cript *this);
sub Cript_criptFile (Cript *this);

sub Cript_destructor (Cript *this);



#endif


cript.c
#include "cript.h"
#include "cript_001.h"
#include "criptbuf.h"



sub Cript_constructor (Cript *this, Settings *setups) {
	__PRINT_DBG("__FUNC: Cript_constructor\n");
	this->setups = setups;

	this->CriptBuf = (CriptBuf *) calloc (1, sizeof (CriptBuf));
	CriptBuf_constructor (this->CriptBuf, Settings_getCriptBufSize (this->setups));
}



void (*Cript_doCripting[][2]) (Cript *this) = {
	{Cript_cript_001, Cript_recript_001}
};



sub Cript_criptFile (Cript *this) {
	__PRINT_DBG("__FUNC: Cript_criptFile\n");
	while (!feof (Settings_getInputFile (this->setups))) {
		Cript_setPreCriptBuf (this);
		(*Cript_doCripting[Settings_getCriptAlgorithm (this->setups)][Settings_isReverse (this->setups)]) (this);
		Cript_writeCript (this);
	}
}



sub Cript_setPreCriptBuf (Cript *this) {
	__PRINT_DBG(("__FUNC: Cript_setPreCriptBuf\n"));
	int i;
	bool flag;

	for (i = 0; i < Settings_getCriptBufSize (this->setups) && (flag = !feof (Settings_getInputFile (this->setups))); i++) {
		CriptBuf_setBit (this->CriptBuf, i, getc (Settings_getInputFile (this->setups)));
		/***/printf (" _ %d: %c\n", i, CriptBuf_getBit (this->CriptBuf, i));
	}
	if (!flag) { /** Ugly style, imho. */
		i--;
	}

	Settings_setCriptBufSize (this->setups, i);
}



sub Cript_writeCript (Cript *this) {
	__PRINT_DBG(("__FUNC: Cript_writeCript\n"));
	for (int i = 0; i < Settings_getCriptBufSize (this->setups); i++) {
		putc (CriptBuf_getBit (this->CriptBuf, i), Settings_getOutputFile (this->setups));
	}
}



sub Cript_destructor (Cript *this) {
	__PRINT_DBG("__FUNC: Cript_destructor\n");
	CriptBuf_destructor (this->CriptBuf);
	this->setups = NULL;
}


В коде выше используется двумерный массив указателей на функции. Двумерный, чтобы можно было легко вызвать алгоритм расшифровки для несимметричного алгоритма шифрования. Я посчитал, что так проще будет добавлять новые алгоритмы шифрования.
В общем, вот тот алгоритм, что используется сейчас.

cript_001.h
#ifndef CRIPT_001_H_INCLUDED
#define CRIPT_001_H_INCLUDED



#include "typedefs.h"
#include "cript_class.h"



#define CRIPT_BLOCK_SIZE 4



sub Cript_cript_001 (Cript *this);
sub Cript_recript_001 (Cript *this);



#endif


cript_001.c
#include "cript_001.h"
#include "settings.h"
#include "criptbuf.h"




char reverseBit (char bite) {
	__PRINT_DBG("__FUNC: reverseBit\n");

	char temp = 0;

	// ...
	#define CHAR_SIZE 8
	for (int i = 0; i < CHAR_SIZE; i++) {
		temp |= ((bite >> i) & 1) << (CHAR_SIZE - 1 - i);
	}
	bite = temp;

	return bite;
}



void Cript_cript_001 (Cript *this) {
	/*
	 * Reverse beat from boundary to center.
	 */

	__PRINT_DBG("__FUNC: Cript_cript_001\n");
	int temp;

	for (int i = 0; i < Settings_getCriptBufSize (this->setups); i += CRIPT_BLOCK_SIZE) {
		if (i + CRIPT_BLOCK_SIZE <= Settings_getCriptBufSize (this->setups)) {
			for (int j = 0; j < CRIPT_BLOCK_SIZE / 2; j++) {
				temp = CriptBuf_getBit (this->CriptBuf, i + j);
				CriptBuf_setBit (this->CriptBuf, i + j, reverseBit (CriptBuf_getBit (this->CriptBuf, i + CRIPT_BLOCK_SIZE - j - 1)));
				CriptBuf_setBit (this->CriptBuf, i + CRIPT_BLOCK_SIZE - j - 1, reverseBit (temp));
			}
		} else {
			for (int j = 0; i + j < Settings_getCriptBufSize (this->setups); j++) {
				CriptBuf_setBit (this->CriptBuf, i + j, reverseBit (CriptBuf_getBit (this->CriptBuf, i + j)));
			}
		}
	}
}



void Cript_recript_001 (Cript *this) {
	__PRINT_DBG("__FUNC: Cript_recript_001\n");
	Cript_cript_001 (this);
}


Из недостатков алгоритма можно выделить очень медленную работу. На 1МБ может уйти около минуты. После выполнения алгоритма каждый блок 4 байта будет побитово развернут. Если последний блок меньше 4 байт, будет побитово разворачиваться каждый байт.

Назначение файлов main.h и main.c должно быть понятно любому.
Я решил не делать "объекты классов", которые описал выше, глобальными, а создавать их в теле функции, передав по ссылке.

main.h
#ifndef MAIN_H_INCLUDED
#define MAIN_H_INCLUDED

#include "typedefs.h"
#include "settings_class.h"

sub showUsage (void);
sub deliteSorceFile (Settings *setups);
sub closeFiles (Settings *setups);

#endif


main.c
#include "typedefs.h"
#include "main.h"
#include "arg.h"
#include "cript.h"



sub showUsage (void) {
	printf (
"Usage:\n\
cript [param] (options) [path to file] [output file name]\n\
\n\
param:\n\
\t-R, --reverse\n\
\t\t> Reverse cript (encript).\n\
\t-r, --remove\n\
\t\t> remove source file.\n\
options:\n\
\t--cript-met=method\n\
\t\t> method={noob}\n\
\n"
	);
}



sub deliteSorceFile (Settings *setups) {
	remove (Settings_getInputFileName (setups));
}



sub closeFiles (Settings *setups) {
	fclose (Settings_getInputFile (setups));
	fclose (Settings_getOutputFile (setups));
}



int main (int argc, char **argv) {
	if (argc == 1) {
		showUsage();
		return 0;
	}

	Settings setups;
	Settings_constructor (&setups);

	Arg arg; Arg_constructor (&arg, &setups);
	Arg_argPars (&arg, argc, argv);

	Cript cript;
	Cript_constructor (&cript, &setups);

	Cript_criptFile (&cript);
	Cript_destructor (&cript);

	closeFiles (&setups);

	if (Settings_isRemove (&setups) == 1) {
		deliteSorceFile (&setups);
	}

	Settings_destructor (&setups);

	return 0;
}


Чтобы не собирать отдельно каждый файл ручками, сделаем Makefile (на виндовс make не завелся, придется собирать от руки).

Makefile
# Make 4.0

CC=gcc

CFLAGS=-c -Os --std=c99


all: cript

cript: main.o settings.o arg.o criptbuf.o cript.o cript_001.o
	$(CC) main.o settings.o arg.o criptbuf.o cript.o cript_001.o -o cript

main.o: main.c
	$(CC) $(CFLAGS) main.c

settings.o: settings.c
	$(CC) $(CFLAGS) settings.c

arg.o: arg.c
	$(CC) $(CFLAGS) arg.c

criptbuf.o: criptbuf.c
	$(CC) $(CFLAGS) criptbuf.c

cript.o: cript.c
	$(CC) $(CFLAGS) cript.c

cript_001.o: cript_001.c
	$(CC) $(CFLAGS) cript_001.c


clean:
	rm -rf *.o cript

clean_o:
	rm -rf *.o

cleancripted:
	rm -rf *.cript

fun:
	rm -rf *


Потом может добавлю графический интерфейс на питоне. Если кому интересно, ссылка на гитхаб. Обновления кидать туда буду.
https://github.com/npcipav/cript
Теги:
шифрование, ООП, Си, pure C, C
Добавлено: 25 Марта 2014 01:47:42 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...