ttki's diary

プログラミング好きな人の日記です

暗号化してみる

最近、暗号化にはまりまくっていますww

暗号化アルゴリズムには、公開鍵と共通鍵がありますが今回は共通鍵です。
公開鍵が登場するまで、暗号化は共通鍵でした。

今回は、少々まともな暗号化アルゴリズムを考えてみます。
で、たぶんシーザーよりは強い暗号化アルゴリズムができました。
名前は、ストリーム暗号を使ったので、SEA ( Stream Encrypt Algorithm ) です。(かっこいいww)

以下コードです。が、あくまでお遊び用に使ってくださいww

#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;


class SEA
{
public:
	int encrypt(int *, int, char *, int);
	int decrypt(int *, int, char *, int);
	int encryptx(int , char*, int);
	int decryptx(int , char*, int);
	int encfile(char*, int, FILE *);
	int decfile(char*, int, char *, FILE *);
};

inline int SEA::encryptx(int num,char key[],int keysz)
{
	int i=num,k,*onkey,out=0,onkeysz,keynum=0,onk = 0;
	onkeysz = (keysz > 20) ? 20 : keysz;
	onkey = (int *)calloc(keysz, sizeof(int));
	for(k=0; k < onkeysz; k++)onkey[k] = (int)key[k];
	
	for(k=0; k < onkeysz - 1; k++)
	{
		onkey[k] ^= onkey[onkeysz - k - 1];
		onkey[k] <<= 3;
	}
	for( k=0; k < onkeysz; k++)
	{
		i = i ^ (onkey[k] * 4);
	}
	for( k=0; k < onkeysz; k++)
	{
		i ^= onkey[k] + (onkey[k] >> 1) * (onkey[k] % 103);
		keynum %= onkey[k] + 31;
		onk += onkey[k];
	}
	
	i *= (keynum + 7);
	
	out = i;
	
	return out;
}

inline int SEA::decryptx(int num,char key[],int keysz)
{
	int i = num;
	int k = 0,*onkey,out=0,onkeysz,keynum = 0,onk = 0;
	
	onkeysz = (keysz > 20) ? 20 : keysz;
	onkey = (int *)calloc(keysz, sizeof(int));
	
	for(k=0; k < onkeysz; k++) onkey[k] = (int)key[k];
	
	for(k=0; k < onkeysz - 1; k++)
	{
		onkey[k] ^= onkey[onkeysz - k - 1];
		onkey[k] <<= 3;
	}
	keynum = 0;
	
	for( k=0; k < onkeysz; k++)
	{
		keynum %= onkey[k] + 31;
		onk += onkey[k];
	}
	i /= (keynum + 7);

	
	for( k=0; k < onkeysz; k++) i ^= onkey[k] + (onkey[k] >> 1) * (onkey[k] % 103);
		
	for( k=0; k < onkeysz; k++) i = i ^ (onkey[k] * 4);

	out = i;
	return out;
}

inline int SEA::encrypt(int *tl,int tlsz,char *key,int keysz)
{
	int i=0;
	for( i=0; i<tlsz; i++) tl[i] = encryptx(tl[i],key,keysz);
	return 0;
}


inline int SEA::decrypt(int *tl,int tlsz,char *key,int keysz)
{
	int i=0;
	for( i=0; i<tlsz; i++) tl[i] = decryptx(tl[i],key,keysz);
	return 0;
}

int SEA::encfile(char *key,int keysz,FILE *fr)
{
	int *tl;
	char*out;
	int i=0,m=0,n=0,fsz=0;
	FILE *fw;
	fw = fopen("sea.sea","wb+");
	{
		fseek(fr,0,2);
		fsz = ftell(fr);
		fseek(fr,0,0);
		tl = new int [fsz]();
		out= new char[fsz]();
	}
	{
		fread(out,sizeof(char),fsz,fr);
		for(i=0; i < fsz; i++) tl[i] = out[i];
		i=0;
	}

	encrypt(tl,fsz,key,keysz);//暗号化

	fwrite(tl,sizeof(int),fsz,fw);
	delete[] tl;
	delete[] out;
	fclose(fw);
	return 0;
}

inline int SEA::decfile(char *key, int keysz, char *filename, FILE *fp)
{
	int *tl;
	char*out;
	int i=0,m=0,n=0,fsz=0;
	FILE *fw;
	if(!(fw=fopen(filename,"wb+"))) return -1;
	{//ファイルサイズ取得 & 配列確保 ブロック
		fseek(fp,0,2);
		fsz = ftell(fp)/4;
		tl = new int[fsz]();
		out= new char[fsz]();
		fseek(fp,0,0);
	}
	fread(tl,sizeof(int),fsz,fp);
	decrypt(tl,fsz,key,keysz);

	for(i=0; i<fsz; i++) out[i] = tl[i];
	fwrite(out,sizeof(char),fsz,fw);

	delete[] tl;
	delete[] out;
	fclose(fw);
	return 0;	
}


int main(int argc,char *argv[])
{
	// 暗号化対象
	int table1 = 65;
	int table2[3] = {12,34,567};

	int k = 0;

	// 暗号化用キー
	char key[20] = "keyword";
	
	// SEA Object
	SEA sea;

	// 表示
	cout << "table1 : " << table1 << endl;
	cout << "table2 : " << table2[0] << " " << table2[1] << " " << table2[2] << endl;

	// 暗号化
	cout << "Encrypt table1 : " << (k = sea.encryptx(table1, key, 20)) << endl;

	// 配列の暗号化
	sea.encrypt(table2,3,key,20);
	cout << "table2 : " << table2[0] << " " << table2[1] << " " << table2[2] << endl;

	// 復号化
	cout << "Decrypt table1 : " << sea.decryptx(k, key, 20) << endl;

	// 配列の復号化
	sea.decrypt(table2, 3, key, 20);
	cout << "table2 : " << table2[0] << " " << table2[1] << " " << table2[2] << endl;

	return 0;
}

こんな感じです。 コードがスパゲッティですいません...

クラスの説明

// SEA class

public:

	// encrypt関数 : 配列の暗号化
	int encrypt(
				int *, // 暗号化対象配列
				int,   // 配列サイズ
				char *,// 復号化 & 暗号化キー 
				int    // 復号化 & 暗号化キーサイズ
				);
	// 戻り値 : 0
	
	// decrypt関数 : 配列の復号化
	int decrypt(
	           	int *, // 復号化対象配列
	           	int,   // 配列サイズ
	           	char *,// 復号化 & 暗号化用キー 
	           	int    // 復号化 & 暗号化用キーサイズ
	           	);
	// 戻り値 : 0
	
	// encryptx関数 : 整数の暗号化
	int encryptx(
				int , // 暗号化対象整数
				char*,// 復号化 & 暗号化用キー 
				int   // 復号化 & 暗号化用キーサイズ
				);
	// 戻り値 : 暗号化後整数 signed int
	
	// decryptx関数 : 整数の復号化
	int decryptx(
	            int , // 復号化対象整数
	            char*,// 復号化 & 暗号化用キー 
	            int   // 復号化 & 暗号化用キーサイズ
	            );
	// 戻り値 : 復号化後整数 signed int
	
	// encfile関数 : ファイルを暗号化 出力ファイル名は常に sea.sea
	int encfile(
				char*, // 復号化 & 暗号化用キー
				int,   // 復号化 & 暗号化用キーサイズ
				FILE * // 暗号化対象ファイルポインタ 読み込みモード
				);
	// 戻り値 : 0
				
	// decfile関数 : ファイルを復号化
	int decfile(
				char*, // 復号化 & 暗号化用キー
				int,   // 復号化 & 暗号化用キーサイズ
				char *,// 復号化後ファイル名
				FILE * // 復号化対象ファイルポインタ 読み込みモード
				);
	// 戻り値 : 0

著作権フリーです。コードを改変してもかまいません。

暗号化って楽しいですね^^b まだ、しばらく暗号化について考えそうです。
それでは^^