Linux下RC4算法的多线程加解密

最近老师布置了下面的任务:

用RC4算法进行加解密,然后用多线程的方式对其进行解密

下面是我自己写的类:

RC4类,负责RC4的加解密,

MyQueue类,负责为线程提供密码包

KeyBox类,密码包,提供getKey()来获得密码

Globle类,封装所有的全局变量

Integer类,负责int转string的操作

Log类,进行日志操作

Lock类,负责进程间的加锁


下面直接贴上代码吧

/*
 * main.cpp
 *
 *  Created on: 2013-5-2
 *      Author: sun
 */
#include "RC4.h"
#include <pthread.h>
#include <stdlib.h>
#include "Globle.h"
#include <sys/time.h>
#define MIN_SLEEP 1000
using namespace std;
//定义全局变量
Globle globle;
//定义密码
#define KEY "9800000"
//定义进程的个数
#define THREADNUM 6
//初始化密码,将以500000为单位把密码放入queue中
void* init_thread(void* arg) {
	globle.thread_count++;
	int start = 0, steep = 500000, max = 9999999;
	while (!globle.breakout && start < max) {
		KeyBox* keybox = new KeyBox(start, steep);
		if (!globle.queue->enter(keybox)) {
			globle.log->writeLog(1, "queue enter error!");
			globle.breakout = true;
			globle.thread_count--;
			return NULL;
		}
		start += steep;
	}
	globle.thread_count--;
	return NULL;
}
//解密线程
void* decrypt_thread(void * arg) {
	cout << "thread creat with " << globle.thread_count << "running" << endl;
	globle.lock.Lock();
	globle.thread_count++;
	globle.lock.Unlock();
//若breakout为true,退出,并把thread_count减1
	if (globle.breakout) {
		cout << "thread breakout!" << endl;
		globle.lock.Lock();
		globle.thread_count--;
		globle.lock.Unlock();
		return NULL;
	}
//开始循环,直到breakout为true
	while (!globle.breakout) {
		if (globle.queue->isEmpty()) //若queue中没有密码包,则退出
			break;
		globle.lock.Lock();
		KeyBox* keybox = globle.queue->out(); //从queue中得到密码包
		globle.lock.Unlock();
		unsigned char s[256] = { 0 };
		while (!globle.breakout && !keybox->isEmpty()) {
			int int_key = keybox->getKey(); //从密码包中获得密码
			char key[256];
			globle.integer.intTostr(key, int_key); //将密码转化成字符串
			globle.rc4.init(s, (unsigned char *) key, strlen(key)); //初始化
			unsigned char data[512];
			globle.rc4.decrypt(data, s, (unsigned char *) globle.pData,
					globle.data_lenth); //解密
//比较,判断解密是否正确
			if (strcmp(globle.DataTemp, (char*) data) == 0
					&& strlen((char*) data) != 0) { //若解密正确,就把密码输出到globle,并把breakout置为true
				cout << "data:" << data << "|datatemp:" << globle.DataTemp
						<< endl;
				globle.key = int_key;
				globle.breakout = true;
				cout << "thread_key = " << globle.key << " is right! with "
						<< globle.thread_count << "running" << endl;
				break;
			}
//		cout<<"data:"<<data<<"|datatemp:"<<globle.DataTemp<<endl;
//		cout<<"thread_key = "<<int_key<<" is wrong!"<<endl;
		}
		delete (keybox); //密码不正确,删除该密码包,重新循环读取下个密码包
	}
	globle.lock.Lock();
	globle.thread_count--; //进程退出,将计数器减1
	globle.lock.Unlock();
	return NULL;
}

int main(void) {
	struct timeval t_start, t_end;
	long cost_time = 0;
	unsigned char s[256] = { 0 }; //S-box
	char key[256] = { KEY }; //初始化密码
	unsigned long len = globle.data_lenth;
	printf("pData = %s    len = %d\n", globle.pData, strlen(globle.pData));
	cout << "key = " << key << ", length = " << strlen(key) << endl;
	globle.rc4.init(s, (unsigned char *) key, strlen(key)); //初始化
	globle.rc4.crypt(s, (unsigned char *) globle.pData, len); //加密
	cout << "pData_len= " << strlen(globle.pData) << ",pData->" << globle.pData
			<< endl;

	pthread_t ids[1000] = { 0 };
//	int i;
//	for (i = 0; i < 100; i++) {
//		ids[i] = i;
//	}
	int i = 0;
//调用初始化线程
	if (pthread_create(ids + i, NULL, init_thread, NULL) != 0) {
		globle.log->writeLog(1, "thread creat failed!");
		return 1;
	}
	i++;
	usleep(250000);
//	cout<<"init over!"<<endl;
//计时,从这里开始计算解密所需的时间
	gettimeofday(&t_start, NULL);
	long start = ((long) t_start.tv_sec) * 1000 + (long) t_start.tv_usec / 1000;
	while (!globle.breakout && i <= THREADNUM) { //创建解密进程
//		cout<<"start thread!"<<endl;
		if (pthread_create(ids + i, NULL, decrypt_thread, NULL) != 0) {
			globle.log->writeLog(1, "thread creat failed!");
			return 1;
		}
		i++;
		usleep(250000);
	}
	while (!globle.breakout) {
		sleep(1);
//		cout<<"11"<<endl;
	}
	//得到解密成功后的时间,计算所需时间放入cost_time变量
	gettimeofday(&t_end, NULL);
	long end = ((long) t_end.tv_sec) * 1000 + (long) t_end.tv_usec / 1000;
	cost_time = end - start;
	ostringstream os;
	os << "key = " << globle.key << " is right! cost " << cost_time << " msec";
	globle.log->writeLog(1, os.str());
	os.clear();
	return 0;
}

/*
 * Globle.h
 *
 *  Created on: 2013-5-4
 *      Author: sun
 */

#ifndef GLOBLE_H_
#define GLOBLE_H_
#include <string.h>
#include "Integer.h"
#include "Lock.h"
#include "MyQueue.h"
#include "RC4.h"
#include "MyLog.h"
#include <stdio.h>
//全局变量类,用来存储所有的全局变量
class Globle {
private:
	unsigned long len;
public:
	RC4 rc4;
	CMutex lock;
	Integer integer;
	char pData[512];
	char DataTemp[512];
	int key;
	bool breakout;
	unsigned long data_lenth;
	int thread_count;
	MyLog* log;
	MyQueue* queue;
	Globle();
	~Globle();
};
#endif /* GLOBLE_H_ */

/*
 * Globle.cpp
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */
#include "Globle.h"

Globle::Globle() {
	log = new MyLog(1, "/home/sun/log", 0);
	queue = new MyQueue();
	len = 512;
	strcpy(pData, "hello,world!");
	strcpy(DataTemp, pData);
	breakout = false;
	data_lenth = strlen(pData);
	thread_count = 0;
}

Globle::~Globle() {
	delete (log);
	delete (queue);
	breakout = true;
	while (thread_count != 0) {
		usleep(100000);
	}
}

/*
 * Integer.h
 *
 *  Created on: 2013-5-5
 *      Author: sun
 */

#ifndef INTEGER_H_
#define INTEGER_H_
#include <string.h>
#include <stdlib.h>
class Integer {
private:
public:
	Integer() {

	}

	int getLen(int i) {
		if (i == 0)
			return 1;
		int j = 0;
		while (i) {
			i = i / 10;
			j++;
		}
		return j;
	}
	void intTostr(char* s, int i) {
		int len = getLen(i);
		int j;
		for (j = len - 1; j >= 0; j--) {
			s[j] = '0' + i % 10;
			i = i / 10;
		}
		s[len] = '\0';
	}
};

#endif /* INTEGER_H_ */

/*
 * KeyBox.h
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */

#ifndef KEYBOX_H_
#define KEYBOX_H_
//密码包类,用来存储从start到start+steep的密码
class KeyBox {
private:
	int start;
	int steep;
public:
	KeyBox(int start, int steep);
	virtual ~KeyBox();
	int getKey();
	bool isEmpty();
	int getStart();
	int getSteep();
};

#endif /* KEYBOX_H_ */

/*
 * KeyBox.cpp
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */

#include "KeyBox.h"

KeyBox::KeyBox(int start, int steep) {
	this->start = start;
	this->steep = steep;
}

KeyBox::~KeyBox() {
}

int KeyBox::getKey() {
	if (steep == 0)
		return -1;
	start++;
	steep--;
	return start;
}

bool KeyBox::isEmpty() {
	if (steep == 0)
		return true;
	return false;
}

int KeyBox::getStart() {
	return start;
}

int KeyBox::getSteep() {
	return steep;
}

#ifndef _Lock_H
#define _Lock_H

#include <pthread.h>

//锁接口类
class ILock
{
public:
    virtual ~ILock() {}

    virtual void Lock() const = 0;
    virtual void Unlock() const = 0;
};

//互斥锁类
class CMutex : public ILock
{
public:
    CMutex();
    ~CMutex();

    virtual void Lock() const;
    virtual void Unlock() const;

private:
    mutable pthread_mutex_t m_mutex;
};

//锁
class CMyLock
{
public:
    CMyLock(const ILock&);
    ~CMyLock();

private:
    const ILock& m_lock;
};


#endif

#include "Lock.h"


//动态方式初始化互斥锁
CMutex::CMutex()
{
    pthread_mutex_init(&m_mutex, NULL);
}

//注销互斥锁
CMutex::~CMutex()
{
    pthread_mutex_destroy(&m_mutex);
}

//确保拥有互斥锁的线程对被保护资源的独自访问
void CMutex::Lock() const
{
    pthread_mutex_lock(&m_mutex);
}

//释放当前线程拥有的锁,以使其它线程可以拥有互斥锁,对被保护资源进行访问
void CMutex::Unlock() const
{
    pthread_mutex_unlock(&m_mutex);
}

//利用C++特性,进行自动加锁
CMyLock::CMyLock(const ILock& m) : m_lock(m)
{
    m_lock.Lock();
}

//利用C++特性,进行自动解锁
CMyLock::~CMyLock()
{
    m_lock.Unlock();
}


/*
 * Queue.h
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */

#ifndef QUEUE_H_
#define QUEUE_H_
#include "KeyBox.h"
//队列类,用来存放KeyBox
class MyQueue {
private:
	KeyBox* queue[1000];
	int head;
	int end;
public:
	MyQueue();
	virtual ~MyQueue();
	KeyBox* out();
	bool enter(KeyBox* keybox);
	bool isEmpty();
};

#endif /* QUEUE_H_ */

/*
 * Queue.cpp
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */

#include "MyQueue.h"
#include <iostream>
MyQueue::MyQueue() {
	head = 0;
	end = 0;
}

MyQueue::~MyQueue() {
	while(!isEmpty()) {
		KeyBox* kb = out();
		delete(kb);
	}

}

bool MyQueue::enter(KeyBox* keybox) {
	*(queue + head) = keybox;
	head++;
//	std::cout<<"head="<<head<<", end="<<end<<std::endl;
	std::cout<<"enter:start="<<keybox->getStart()<<",end="<<keybox->getSteep()<<std::endl;
	if (head >= 1000)
		head = 0;
	if (head == end)
		return false;
	return true;
}

KeyBox* MyQueue::out() {
	if (head == end)
		return NULL;
	KeyBox* keybox = *(queue + end++);
	std::cout<<"out:start="<<keybox->getStart()<<",end="<<keybox->getSteep()<<std::endl;
	if (end >=1000)
		end = 0;
	return keybox;

}

bool MyQueue::isEmpty() {
	if (head == end) {
		return true;
	}
	return false;
}

/*
 * RC4.h
 *
 *  Created on: 2013-5-4
 *      Author: sun
 */
//初始化,s:打乱数组, key:密钥, Len:密钥的长度
#ifndef RC4_H_
#define RC4_H_

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
//RC4加密类,用来对数据加解密
class RC4{
public:
	RC4(){};
	void init(unsigned char* s, unsigned char* key, unsigned long len);
	void crypt(unsigned char* sbox, unsigned char *Data, unsigned long Len);
	unsigned char* decrypt(unsigned char* Data, unsigned char* sbox, unsigned char *pData, unsigned long Len);
};
#endif


/*
 * RC4.cpp
 *
 *  Created on: 2013-5-15
 *      Author: sun
 */
#include "RC4.h"
void RC4::init(unsigned char *s, unsigned char *key, unsigned long Len) {
	int i = 0, j = 0, k[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i < 256; i++) {
		s[i] = i;
		k[i] = key[i % Len];
	}
	for (i = 0; i < 256; i++) {
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];     //交换s[i]和s[j]
		s[j] = tmp;
	}
}
//加密解密函数,s:经过密码随机排列过的数组, Data:要加密的数据, Len:Data的长度
void RC4::crypt(unsigned char* sbox, unsigned char *Data, unsigned long Len) {
	unsigned char s[256];
	int x = 0, y = 0, t;
	unsigned long i;
	for (t=0; t<256; t++) {
		s[t] = sbox[t];
	}
	t = 0;
	unsigned char tmp;
	for (i = 0; i < Len; i++) {
		x = (x + 1) % 256;
		y = (y + s[x]) % 256;
		tmp = s[x];
		s[x] = s[y];     //交换s[x]和s[y]
		s[y] = tmp;
		t = (s[x] + s[y]) % 256;
		Data[i] ^= s[t];     //取异或
	}
}

unsigned char* RC4::decrypt(unsigned char* Data, unsigned char* sbox, unsigned char *pData, unsigned long Len) {
	unsigned char s[256];
	int x = 0, y = 0, t;
	unsigned long i;
	for (t=0; t<256; t++) {
		s[t] = sbox[t];
	}
	for(i=0; i<Len; i++){
		Data[i] = pData[i];
	}
	t = 0;
	unsigned char tmp;
	for (i = 0; i < Len; i++) {
		x = (x + 1) % 256;
		y = (y + s[x]) % 256;
		tmp = s[x];
		s[x] = s[y];     //交换s[x]和s[y]
		s[y] = tmp;
		t = (s[x] + s[y]) % 256;
		Data[i] ^= s[t];     //取异或
	}
	Data[Len] = '\0';
	return Data;
}


最后结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值