程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++ 使用Tea算法進行加密解密。

c++ 使用Tea算法進行加密解密。

編輯:C++入門知識

c++ 使用Tea算法進行加密解密。


最近在進行cocos2dx的項目,涉及到文件加密的問題,而解密實在游戲加載的時候進行。 因此在加密功能之上還必須要求盡可能快速。所以選擇了tea加密算法。     而加密過程使用window的commond 項目,進行針對文件夾或者文件加密。       閒話少說,直接上代碼。   加密部分,由於對於win commond line 項目不是很熟悉, 所以做的比較粗糙。   // tea.cpp : 定義控制台應用程序的入口點。 //   #include "stdafx.h" #include "Tea/TeaEd.h" #include <fstream> #include <string> #include <iostream> #include<io.h> #include <windows.h>   #include <cstring> #include <fstream> using namespace std;   //判斷是一個文件夾 inline bool IsFolder(const string & strWorkSpace, string &fileName, string & filePath) {     bool bCheck = false;     fileName = strWorkSpace;     filePath = "";     size_t pos = strWorkSpace.find_last_of("\\");     if (pos != std::string::npos)     {         filePath = strWorkSpace.substr(0, pos + 1);         fileName = strWorkSpace.substr(pos + 1);           pos = fileName.find_last_of(".");         if (pos == std::string::npos)         {             bCheck = true;             fileName = "";             filePath = strWorkSpace;         }       }     return bCheck; }   int doMethod(const string & str) {   //測試選項。輸入輸入1,則是解密一個文件,並輸出到解密之後的內容     if (str == "1")     {         cout << "將要解密的文件投入:" << endl;         string strFileNameTmp;         cin >> strFileNameTmp;         string str1;         string str2;         bool bCheck = IsFolder(strFileNameTmp, str1, str2);         if (bCheck)         {             cout << "測試解密的必須是一個文件,請按下回車繼續操作" << endl;             system("PAUSE");               cout << "- 選擇解密某個文件進行測試請輸入 1 回車" << endl;             cout << "- 選擇進行加密請輸入 其他字符 回車" << endl;             string strInputTmp;             cin >> strInputTmp;             doMethod(strInputTmp);             return 0;         }   //這是一個單例加密類。負責加密和解密         GetCryTool()->deCryWithFileName(strFileNameTmp, "");           return 0;     }           cout << "1.拖入為文件" << endl;     cout << "將在該文件同目錄下創建一個以 [文件名 + '_cryfile'] 為規則的文件夾" << endl;     cout << endl;     cout << "2.拖入為文件夾" << endl;     cout << "將在該文件夾同級目錄下創建一個cryfolder文件夾,加密之後的文件都在這裡" << endl;     cout << "\n\n將文件或者文件夾拖入下方 :" << endl;     string strWorkPath;     cin >> strWorkPath;       string strFileName = "";     string strFilePath = "";     cout << "Path : " << strWorkPath << endl;     bool bCheck = IsFolder(strWorkPath, strFileName, strFilePath);     if (bCheck)     {         do         {             //write path and create cry file folder             size_t pos = strFilePath.find_last_of("\\");             if (pos != std::string::npos)             {                 strFilePath = strFilePath.substr(0, pos + 1);             }               strFilePath.append("cryfolder");               string strCreateForderCMD = "md ";             strCreateForderCMD.append(strFilePath);             system(strCreateForderCMD.c_str());           } while (0); //如果是一個文件夾, 則要判斷這個文件夾下所有文件,並寫入allFiles.txt文件中。然後按行讀取這個文件,得到每個要加密文件的路徑         vector<string> oVecLines;         string sline;         do         {             //create record file txt named allFiles             //and del it             string strAllFilePath = strFilePath;             strAllFilePath.append("\\allFiles.txt");               string strCmd = "cmd /c dir ";             strCmd.append(strWorkPath);             strCmd.append("\\*.* /a-d /b /s >");             strCmd.append(strAllFilePath);             cout << strCmd << endl;             system(strCmd.c_str());               ifstream ifs(strAllFilePath);             while (ifs && getline(ifs, sline))             {                 cout << sline << endl;                 oVecLines.push_back(sline);             }             ifs.close();               string strDelCMD = "del ";             strDelCMD.append(strAllFilePath);             system(strDelCMD.c_str());           } while (0);   //遍歷文件路徑。依次加密。         for (size_t i = 0; i < oVecLines.size(); i++)         {             sline = oVecLines[i];             string strTmpfileName = "";             string strTmpFilePath = "";             bool bCheck = IsFolder(sline, strTmpfileName, strTmpFilePath);             if (!bCheck)             {                 string strOutFilePath = strFilePath;                 strOutFilePath.append("\\");                 strOutFilePath.append(strTmpfileName);                 GetCryTool()->enCryWithFileName(sline, strOutFilePath);             }         }       }     else     {         string strTmpWirtePath = strFilePath;         do         {             //write path and create cry file folder             size_t pos = strFilePath.find_last_of("\\");             if (pos != std::string::npos)             {                 strFilePath = strFilePath.substr(0, pos + 1);             }               size_t szPos = strFileName.find_last_of(".");             if (szPos != std::string::npos)             {                 strTmpWirtePath.append(strFileName.substr(0, szPos));                 strTmpWirtePath.append("_cryfile");             }               string strCreateForderCMD = "md ";             strCreateForderCMD.append(strTmpWirtePath);             system(strCreateForderCMD.c_str());           } while (0);           strTmpWirtePath.append("\\");         strTmpWirtePath.append(strFileName);         GetCryTool()->enCryWithFileName(strWorkPath, strTmpWirtePath);     }   }   int _tmain(int argc, _TCHAR* argv[]) {       char buf[1000];     GetModuleFileNameA(NULL, buf, 1000);     string strKeyPath(buf);     string strKeyfilepath = strKeyPath;     size_t szPos = strKeyfilepath.find_last_of("\\");     if (szPos != std::string::npos)     {         strKeyfilepath = strKeyfilepath.substr(0, szPos + 1);     }       string strKeyPrePath = strKeyfilepath; //key_prepared.txt是用來存儲明文密碼的文件。 在加密項目下     strKeyPrePath.append("key_prepared.txt"); //key_result.txt是將key加密之後的密碼。同樣也在加密項目下     strKeyfilepath.append("key_result.txt");     string strKeyPre = "";       do      {         ifstream ifs(strKeyPrePath);         while (ifs && getline(ifs, strKeyPre))         {             break;         }         ifs.close();     } while (0);       if (strKeyPre.empty())     {         cout << "沒有輸入密碼,請在" << strKeyPrePath << " 中寫入密碼" << endl;         return 0;     }         string str;     cout << "[ 當前密碼為 :" << strKeyPre <<" ]"<< endl;     cout << "- 修改密碼請輸入'key'回車" << endl;     cout << "- 選擇解密某個文件進行測試請輸入1回車" << endl;     cout << "- 選擇進行加密請輸入其他回車" << endl;     cin >> str;   //判斷是否要修改密碼     if (str == "KEY" || str == "key")     {         system("cls");         string strNewKeyStr;         cout << "請輸入新密碼 :" << endl;         cin >> strNewKeyStr;         GetCryTool()->setUpTea(strNewKeyStr, strKeyfilepath);                  cout << "密碼已經修改.請繼續操作" << endl;         cout << "- 選擇解密某個文件進行測試請輸入1回車" << endl;         cout << "- 選擇進行加密請輸入其他回車" << endl;         cin >> str;         doMethod(str);     }     else     {         GetCryTool()->setUpTea(strKeyPre, strKeyfilepath);         doMethod(str);     }                system("PAUSE");       return 0; }     這面的代碼是主函數部分。   然後放上加密解密的核心部分。   在TeaEd.h中   class TeaEd { public:     /*         isNetByte is unuseful param in this project.     */     TeaEd(const byte * key,    int round = 32, bool isNetByte = false);     TeaEd(const TeaEd &rhs);     TeaEd & operator = (const TeaEd &rsh);       void encrypt(const byte * in, byte * out);     void decrypt(const byte * in, byte * out); private:     void encrypt(const ulong * in, ulong * out);     void decrypt(const ulong * in , ulong * out);     //the method under is use for net data.  //not useful.     ulong ntoh(ulong netlong){return _isNetByte ? /*ntohl(netlong)*/netlong : netlong;}     ulong hton(ulong hostlong){ return _isNetByte ? /*htonl(hostlong)*/hostlong : hostlong; }   protected:     int _round;//iteration round to encrypt or decrypt     // Not useful in this project.     bool _isNetByte;//whether input bytes come from network.     byte _key[16];//encrypt or decrypt key };   在TeaEd.cpp文件中     TeaEd::TeaEd(const byte * key,    int round/*= 32*/, bool isNetByte/*false*/): _round(round), _isNetByte(false/*isNetByte*/) {     if (key != 0)     {         memcpy(_key,key,16);     }else     {         memset(_key,0,16);     } } TeaEd::TeaEd(const TeaEd &rhs): _round(rhs._round), _isNetByte(/*rhs._isNetByte*/false) {     memcpy(_key,rhs._key,16); }   TeaEd & TeaEd::operator = (const TeaEd &rsh) {     if (&rsh != this)     {         _round = rsh._round;         _isNetByte = /*rsh._isNetByte*/false;         memcpy(_key, rsh._key, 16);     }     return *this; } void TeaEd::encrypt(const byte * in, byte * out) {      encrypt((const ulong*)in, (ulong*)out); } void TeaEd::decrypt(const byte * in, byte * out) {     decrypt((const ulong*)in, (ulong*)out); }   void TeaEd::encrypt(const ulong * in, ulong * out) {     ulong * k = (ulong*)_key;     register ulong y = in[0];//ntoh(in[0]);     register ulong z = in[1];//ntoh(in[1]);     register ulong a = k[0];//ntoh(k[0]);     register ulong b = k[1];//ntoh(k[1]);     register ulong c = k[2];//ntoh(k[2]);     register ulong d = k[3];//ntoh(k[3]);     register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */     register int round = _round;     register ulong sum = 0;     while (round--)      {             /* basic cycle start */         sum += delta;         y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);         z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);     }/* end cycle */     out[0] = y;//ntoh(y);     out[1] = z;//ntoh(z); }   void TeaEd::decrypt(const ulong * in , ulong * out) {     ulong *k = (ulong*)_key;     register ulong y = in[0];//ntoh(in[0]);     register ulong z = in[1];//ntoh(in[1]);     register ulong a = k[0];//ntoh(k[0]);     register ulong b = k[1];//ntoh(k[1]);     register ulong c = k[2];//ntoh(k[2]);     register ulong d = k[3];//ntoh(k[3]);     register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */     register int round = _round;     register ulong sum = 0;       if (round == 32)         sum = 0xC6EF3720; /* delta << 5*/     else if (round == 16)         sum = 0xE3779B90; /* delta << 4*/     else         sum = delta << static_cast<int>(logbase(2, round));          while (round--)      {             /* basic cycle start */          z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);         y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);         sum -= delta;     }/* end cycle */     out[0] = y;//ntoh(y);     out[1] = z;//ntoh(z); }       因為加密解密需要在全局使用一個密碼。所以我們用一個單例類管理加密解密功能。   同樣都在TeaEd.h 和TeaEd.cpp中。   頭文件的單例管理類部分。由於在測試的時候嘗試了很多很多辦法。 所以有很多無用的接口。真正使用到的接口只有   void enCryWithFileName(const string & strFile,const string & strOutFile); void deCryWithFileName(const string & strFileName,const string& strOutfile);   這兩個接口。 其中decry 部分使用到的第二個參數無用。   單例類在構造之初就通過密碼創建了Tea對象,由於工作比較忙, 先不詳細介紹了。。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved