利用按位異或運算加密文件(用c語言、c++和vb寫的)-創(chuàng)新互聯(lián)

這是我用來練習的程序,功能是用密碼加密文件,寫了兩個版本:第一個完全用c++寫,練習類的繼承、操作符重載;第二個嘗試用c寫dll,vb調(diào)用dll的函數(shù)。

專注于為中小企業(yè)提供成都網(wǎng)站設計、成都網(wǎng)站制作服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)達州免費做網(wǎng)站提供優(yōu)質的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了千余家企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉變。
原理

在第一次學按位異或算符“^”時,我注意到這個運算是可逆的,即(a^b)^b=a,于是就想到可以利用按位異或運算將文件加密。后來就寫了加密程序,原理是用特定長度的char類型作為密碼,將文件內(nèi)容與密碼逐字節(jié)異或運算,將運算結果寫入另一個文件,密碼長度不夠就從頭循環(huán)。

c0356b1388ea41cbb4fd9e78203d17a2.png

可以看出,將加密后的文件用相同的密碼再次“加密”后就可以解密。


密碼形式

密碼形式是二進制文件“key.bin”。char類型可以放不可打印字符,于是我想到從二進制文件中讀取密碼,用16進制編輯器編輯二進制文件(我用的是flexhexeditor)。二進制文件的前4個字節(jié)是unsigned int型變量,是密碼長度,密碼長度不能太長,我初步定為不超過256字節(jié);從第5個字節(jié)開始到文件結尾就是密碼,文件末尾多出一些內(nèi)容也沒關系。


加密后的文件名

保存的文件文件名,我是直接加一個擴展名“.加密文件”,如果文件本身擴展名就是“.加密文件”,就把擴展名去掉。


兩個版本的區(qū)別

c++版是將文件拖動到exe程序上打開,程序在工作目錄打開“key.bin”(如果是拖動打開或選擇打開方式后雙擊打開,則工作目錄為文件所在目錄)。c和vb版是可以選擇文件,用的是winapi函數(shù)GetOpenFileName。另外c和vb版可以輸入字符串作為密碼,或者從bmp文件產(chǎn)生密碼,是當時考慮各種密碼形式時的產(chǎn)物。

c++代碼如下,vb和c混合寫的由于有多個文件,不貼代碼,發(fā)文件:按位異或文件加密,vb

#include#include#include#include//嘗試類繼承的練手作
#define scanlength 65536

class keychar;

class mywords {
	protected:
		unsigned int length;//字節(jié)數(shù)
		char *str;
	public:
		mywords(char * words, int length = 0);
		mywords(int len);
		mywords();
		~mywords();
		int read(std::ifstream &in);//默認從文件中讀取length字節(jié)的內(nèi)容 
		int read(std::ifstream &in, int len);//指定讀取的長度
		void write(std::ofstream &out, int len);//將str指向的len字節(jié)內(nèi)容寫入文件
		unsigned int getlength();
		mywords& operator =(mywords& words);
		mywords& operator =(char* words);
		//因為字節(jié)數(shù)不一定相等,mywords的按位異或運算不滿足交換律
		mywords& operator ^=(keychar& key);
};

class keychar : public mywords {
	public:
		static const int keychar_size = 256;
		void keyread(std::ifstream &in);
		void keywrite(std::ofstream &out);
};

int main(int argc, char *argv[]) {
	int n;
	mywords scan(scanlength); //在一定范圍內(nèi),scanlength越長,速度越快 
	keychar key;
	std::ifstream in, keyin;
	std::ofstream out;
	if (argc >1) {
		//識別擴展名,有".加密文件"則刪,無則追加
		char *file;
		file = strrchr(argv[1], '\\') + 1;//每層文件夾后都有\(zhòng),所以定位到最后一個 
		char filename[strlen(file) + 64];//預留一些空間,防止內(nèi)存溢出 
		strcpy(filename, file);
		file = strrchr(filename, '.');//定位到最后一個'.',就是擴展名,“電影.mp4.txt”是純文本文件 
		if (!file || strcmp(file, ".加密文件")) {
			strcpy(filename + strlen(filename), ".加密文件");
		} else {
			*file = '\0';
		}
		//打開文件
		in.open(argv[1], std::ios::binary);
		out.open(filename, std::ios::binary);
		keyin.open("key.bin", std::ios::binary);
		//讀取key文件
		if (keyin) {
			key.keyread(keyin);
			keyin.close();
		}
		//讀取文件并加密保存
		while (!in.eof()) {
			n = scan.read(in);
			scan ^= key;
			scan.write(out,n);
		}
	}
	in.close();
	out.close();
	return 0;
}

mywords::mywords() {
	length = 0;
	str = NULL;
}

mywords::mywords(int len) {
	length = len;
	str = (char*)malloc(length);
}

mywords::mywords(char*words, int length) {
	if (length< 1)length = strlen(words);
	str = (char*)malloc(length);
	for (int i = 0; i< length; i++) {
		str[i] = words[i];
	}
}

mywords::~mywords() {
	if (str)free(str);
}

int mywords::read(std::ifstream &in){
	in.read(str,length);
	return in.gcount();
}

int mywords::read(std::ifstream &in, int len){
	in.read(str,len);
	return in.gcount();
}

void mywords::write(std::ofstream &out, int len){
	out.write(str,len);
}

unsigned int mywords::getlength() {
	return length;
}

mywords& mywords::operator ^=(keychar& key) {
	unsigned int i, j;
	if (key.getlength() >0)
		for (i = j = 0; i< length; i++, j++) {
			if (j >= key.getlength())j -= key.getlength();
			str[i] ^= key.str[j];
		}
	return *this;
}

mywords& mywords::operator =(mywords& words) {
	unsigned int i;
	length = words.length;
	if (str)free(str);
	str = (char *)malloc(length);
	for (i = 0; i< words.length; i++)str[i] = words.str[i];
	return *this;
}

mywords& mywords::operator =(char* words) {
	unsigned int i;
	length = strlen(words);
	if (str)free(str);
	str = (char*)malloc(length);
	for (i = 0; i< length; i++)str[i] = words[i];
	return *this;
}

void keychar::keyread(std::ifstream &in) {
	if (str)free(str);
	length = 0;
	str = NULL;
	in.read((char*)&length, 4);
	if (length >keychar_size)
		length = ((length & 0xff)<< 24) + ((length & 0xff00)<< 8) + ((length & 0xff0000) >>8) + ((length & 0xff000000) >>24);
	if (length >keychar_size) {
		printf("error: key文件格式錯誤,不加密(解密)輸出\n");
		system("pause");
	}
	if (length) {
		str = (char*)malloc(length);
		in.read(str, length);
	}
}

void keychar::keywrite(std::ofstream &out) {
	out.write((char*)&length, 4);
	if (length)out.write(str, length);
}

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:利用按位異或運算加密文件(用c語言、c++和vb寫的)-創(chuàng)新互聯(lián)
標題網(wǎng)址:http://bm7419.com/article22/dgoscc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作商城網(wǎng)站、微信小程序靜態(tài)網(wǎng)站、手機網(wǎng)站建設、微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作