最近老师布置了下面的任务:
用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;
}
最后结果: