c++ 使用Tea算法进行加密解密。
转载请注明链接 : http://www.cnblogs.com/bluen/p/4453354.html
最近在进行cocos2dx的项目,涉及到文件加密的问题,而解密实在游戏加载的时候进行。 因此在加密功能之上还必须要求尽可能快速。所以选择了tea加密算法。
我主要参考了这篇博客 http://www.cnblogs.com/huhu0013/p/3334890.html
而加密过程使用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); }
转载请注明链接 : http://www.cnblogs.com/bluen/p/4453354.html
因为加密解密需要在全局使用一个密码。所以我们用一个单例类管理加密解密功能。
同样都在TeaEd.h 和TeaEd.cpp中。
头文件的单例管理类部分。由于在测试的时候尝试了很多很多办法。 所以有很多无用的接口。真正使用到的接口只有
void enCryWithFileName(const string & strFile,const string & strOutFile);
void deCryWithFileName(const string & strFileName,const string& strOutfile);
这两个接口。 其中decry 部分使用到的第二个参数无用。
单例类在构造之初就通过密码创建了Tea对象,由于工作比较忙, 先不详细介绍了。。
#define GetCryTool()\ CryTool::getInstance() class CryTool { public: static CryTool * getInstance(); void setUpTea(const string & strKey,const string & strKeyFile); void enCryWithFileName(const string & strFile,const string & strOutFile); void deCryWithFileName(const string & strFileName,const string& strOutfile); void testCryUseHex(const string & strfile); void testDeCryUseHex(); void testCry(const string & strFileName); void testDeCry(); void strEnCry(); void strDeCry(); void testWriteHex(byte * poData,size_t szSize, const string & strFileName); public: void cryFileByName(const string & strFileName); void normalContentEncry(const string & strContent, byte * outData); void hexContentEncry(const string & strContent, byte * outData); private: void partHexStringEncry(const string & strHexPart,byte * outData); void enCry(const byte * inData, byte * outData); void deCry(const byte * inData, byte * outData); public: protected: TeaEd * m_poTea; CryTool(); ~CryTool(); protected: static CryTool * s_poCryTool; };
实现文件的单例管理部分。
CryTool * CryTool::s_poCryTool = nullptr; CryTool * CryTool::getInstance() { if (s_poCryTool == nullptr) { s_poCryTool = new CryTool(); } return s_poCryTool; } CryTool::CryTool() { srand((unsigned)time(0)); } void CryTool::setUpTea(const string & strKey,const string & strKeyPath) { const string keyStr = strKey; byte bMd5[64]; char strMd5[36]; librad_md5_calc(bMd5, (byte *)(keyStr.c_str()), keyStr.length()); hex_dump(bMd5, 16, strMd5); const int SIZE_KEY = 16; byte key[SIZE_KEY]; string strKeyOut(strMd5); cout << "密码保存路径为 :" << strKeyPath << endl; testWriteHex((byte*)strKeyOut.c_str(), strKeyOut.size(), strKeyPath); size_t size_key = hexStringToBytes(strKeyOut, key); m_poTea = new TeaEd(key, 16, false); } CryTool::~CryTool() { if (m_poTea) delete m_poTea; } inline void printTblData(CryFileTool::Data oData) { byte * poData = oData.getBytes(); size_t szDataSize = oData.getSize(); static char accBuf[1024 * 1024]; bool bCheck = CodeConvert("UTF-8", "UTF-16", (char *)poData, (long int)szDataSize, accBuf, (long int)sizeof(accBuf)); if (!bCheck) { cout << "解码转化失败" << endl; return; } char* pStart = (char *)accBuf; char* pEnd = NULL; vector<string > roVecLines; while (true) { bool bEnd = false; string strLine; pEnd = strstr(pStart, "\r\n"); if (NULL == pEnd) { bEnd = true; strLine = pStart; } else { strLine.assign(pStart, pEnd); } if (strLine.length() != 0) { roVecLines.push_back(strLine); } if (bEnd) { break; } pStart = pEnd + 2; } for (size_t i = 0; i < roVecLines.size(); i++) { printf("%s\n", roVecLines[i].c_str()); } } void CryTool::enCryWithFileName(const string & strFile, const string& strOutfile) { CryFileTool::Data oData = CryFileTool::getData(strFile, false); byte * byData = oData.getBytes(); size_t szDataSize = oData.getSize(); static char acFileBuf[1024 * 1024]; memset(acFileBuf, 0, sizeof(acFileBuf)); const int SIZE_IN = 8, SIZE_OUT = 8, SIZE_KEY = 16; byte plain[SIZE_IN] = { 0 }, crypt[SIZE_OUT] = { 0 }, key[SIZE_KEY] = { 0 }; size_t szAcFileBufSize = 0; char cLen = szDataSize % 8 + '0'; memcpy(acFileBuf + szAcFileBufSize, &cLen, 1); //sprintf(acFileBuf + szAcFileBufSize, "%s", &cLen); szAcFileBufSize += 1; for (size_t i = 0; i < szDataSize; i += 8) { int nLostCount = szDataSize - i; if (nLostCount < 8) { byte * poHead = &(byData[i]); int remain = 8 - nLostCount; memcpy(plain, poHead, remain); for (size_t j = 0; j < remain; j++) { char c = random(128) & 0xff; plain[nLostCount + j] = c; } } else { byte * poHead = &(byData[i]); memcpy(plain, poHead, 8); } m_poTea->encrypt(plain, crypt); memcpy(acFileBuf + szAcFileBufSize, crypt, 8); //sprintf(acFileBuf + szAcFileBufSize, "%s", crypt); szAcFileBufSize += 8; } testWriteHex((byte*)acFileBuf, szAcFileBufSize, strOutfile); } void CryTool::deCryWithFileName(const string & strFileName, const string& strOutfile) { static char accBufData[1024 * 1024]; size_t szBufDataSize = 0; memset(accBufData, 0, sizeof(accBufData)); CryFileTool::Data oData = CryFileTool::getData(strFileName, false); byte * byData = oData.getBytes(); size_t szDataSize = oData.getSize(); char cCountNum = byData[0]; int nCountNum = cCountNum - '0'; if (nCountNum > 8 || nCountNum < 0) { return; } //Important byte * byEncData = (byte *)&(byData[1]); int len = szDataSize - 1; int i; const int SIZE_IN = 8, SIZE_OUT = 8, SIZE_KEY = 16; byte plain[SIZE_IN] = { 0 }, crypt[SIZE_OUT] = { 0 }, key[SIZE_KEY] = { 0 }; for (i = 0; i < len; i += SIZE_IN) { byte * poHead = &byEncData[i]; memcpy(crypt, poHead, SIZE_IN); m_poTea->decrypt(crypt, plain); if (i >= (len - SIZE_IN) && nCountNum != 0) { memcpy(accBufData + szBufDataSize, plain, nCountNum); szBufDataSize += nCountNum; } else { memcpy(accBufData + szBufDataSize, plain, SIZE_OUT); szBufDataSize += SIZE_IN; } } static char accBuf[1024 * 1024]; bool bCheck = CodeConvert("UTF-16", "UTF-8", (char *)accBufData, (long int)len, accBuf, (long int)sizeof(accBuf)); if (!bCheck) { cout << "解码转化失败" << endl; return; } char* pStart = (char *)accBuf; char* pEnd = NULL; vector<string > roVecLines; while (true) { bool bEnd = false; string strLine; pEnd = strstr(pStart, "\r\n"); if (NULL == pEnd) { bEnd = true; strLine = pStart; } else { strLine.assign(pStart, pEnd); } if (strLine.length() != 0) { roVecLines.push_back(strLine); } if (bEnd) { break; } pStart = pEnd + 2; } for (size_t i = 0; i < roVecLines.size(); i++) { printf("%s\n", roVecLines[i].c_str()); } return; } void CryTool::strEnCry() { CryFileTool::Data oData = CryFileTool::getData("C:\\Users\\tie\\Desktop\\battleskill.tbl", false); byte * byData = oData.getBytes(); size_t szDataSize = oData.getSize(); const int SIZE_IN = 8, SIZE_OUT = 8, SIZE_KEY = 16; byte plain[SIZE_IN] = { 0 }, crypt[SIZE_OUT] = { 0 }, key[SIZE_KEY] = { 0 }; int len = (int)szDataSize; static char acFileBuf[1024 * 1024] = {0}; size_t szData = 0; char cLen = szDataSize % 8 + '0'; sprintf(acFileBuf + szData, "%s", &cLen); szData += 1; for (size_t i = 0; i < len; i += 8) { if (len - i < 8) { byte * poHead = &(byData[i]); int remain = 8 - (len - i); memcpy(plain, poHead, remain); for (size_t j = 0; j < remain; j++) { char c = random(128) & 0xff; plain[len - i + j] = c; } } else { byte * poHead = &(byData[i]); memcpy(plain, poHead, 8); //strNow = src.substr(i, 8); } // size_t size_in = stringToBytes(strNow, plain); m_poTea->encrypt(plain, crypt); sprintf(acFileBuf + szData, "%s", crypt); szData += 8; //strCrypt.append((char*)crypt); //+= bytesToHexString(crypt, SIZE_OUT);// .append((char*)crypt);//; } char cCount = acFileBuf[0]; int rlen = cCount - '0'; byte * encBytes = (byte *)&(acFileBuf[1]); int len2 = szData, i; static char acFileBuf2[1024 * 1024]; size_t szFileSize = 0; const int SIZE_IN2 = 16; byte plain2[SIZE_IN2] = { 0 }; for (i = 0; i < len2; i += SIZE_IN2) { byte * poHeadByte = &encBytes[i]; memcpy(crypt, poHeadByte, SIZE_IN2); m_poTea->decrypt(crypt, plain2); if (i >= len2 - SIZE_IN2 && rlen != 0) { sprintf((char *)acFileBuf2 + szFileSize, "%s", plain2); szFileSize += rlen; } else { sprintf((char *)acFileBuf2 + szFileSize, "%s", plain2); szFileSize += SIZE_OUT; } } bool bCheck = CodeConvert("UTF-8", "UTF-16", acFileBuf2, (long int)szFileSize, acFileBuf, (long int)sizeof(acFileBuf)); //string ssss; string strr; cin >> strr; return; } void CryTool::strDeCry() { return; CryFileTool::Data oData = CryFileTool::getData("C:\\Users\\tie\\Desktop\\newEncry.txt", false); byte * byData = oData.getBytes(); size_t szDataSize = oData.getSize(); string src = byteToString(byData, szDataSize); int rlen = src.at(0) - '0'; string enc = src.substr(1), strOut = ""; int len = enc.length(), i; const int SIZE_IN = 16, SIZE_OUT = 8, SIZE_KEY = 16; byte plain[SIZE_IN] = { 0 }, crypt[SIZE_OUT] = { 0 }, key[SIZE_KEY] = { 0 }; static char acFileBuf[1024 * 1024]; //size_t szFileSize = 0; for (i = 0; i < len; i += SIZE_IN) { string strNow = enc.substr(i, SIZE_IN); size_t size_in = hexStringToBytes(strNow, crypt); m_poTea->decrypt(crypt, plain); if (i >= len - SIZE_IN && rlen != 0) { strOut += byteToString(plain, rlen); //sprintf((char *)acFileBuf + szFileSize, "%s", plain); //szFileSize += rlen; //strOut += bytesToHexString(plain, rlen); } else{ strOut += byteToString(plain, SIZE_OUT); //sprintf((char *)acFileBuf + szFileSize, "%s", plain); //szFileSize += SIZE_OUT; //strOut += bytesToHexString(plain, SIZE_OUT); } }// string dest = ""; dest = strOut; //wchar_t * wcP = ANSITOUnicode(acFileBuf); //static char acFileBuf[1024 * 1024]; bool bCheck = CodeConvert("UTF-8", "UTF-16", (char *)strOut.c_str(), (long int)strOut.size(), acFileBuf, (long int)sizeof(acFileBuf)); char* pStart = (char *)acFileBuf; char* pEnd = NULL; vector<string > roVecLines; while (true) { bool bEnd = false; string strLine; pEnd = strstr(pStart, "\r\n"); if (NULL == pEnd) { bEnd = true; strLine = pStart; } else { strLine.assign(pStart, pEnd); } if (strLine.length() != 0) { roVecLines.push_back(strLine); } if (bEnd) { break; } pStart = pEnd + 2; } for (size_t i = 0; i < roVecLines.size(); i ++) { printf("%s\n", roVecLines[i].c_str()); } //string ssss; string strr; cin >> strr; return; // string dest; // dest = strOut; // FILE *fp; // fopen_s(&fp, "C:\\Users\\tie\\Desktop\\newDecry.txt", "wb"); // fwrite(dest.c_str(), sizeof(unsigned char), dest.size(), fp); // fclose(fp); } void CryTool::enCry(const byte * inData, byte * outData) { m_poTea->encrypt(inData, outData); } void CryTool::deCry(const byte * inData, byte * outData) { m_poTea->decrypt(inData, outData); } void CryTool::normalContentEncry(const string & strContent, byte * outData) { vector<unsigned char> vecTmp(strContent.begin(),strContent.end()); string strHexContent = bytesToHexString(&vecTmp.front(), strContent.size()); hexContentEncry(strHexContent, outData); } void CryTool::testCryUseHex(const string & strfile) { CryFileTool::Data oData = CryFileTool::getData(strfile, false); byte * byData = oData.getBytes(); size_t szDataSize = oData.getSize(); string strHexContext = bytesToHexString(byData, szDataSize); strHexContext.append(" "); size_t szGroupCount = strHexContext.size() / 24; size_t szLostCount = strHexContext.size() % 24; string strHex = bytesToHexString(oData.getBytes(), oData.getSize()); vector<byte> vectest(strHex.begin(), strHex.end()); testWriteHex(&vectest.front(), vectest.size(), "C:\\Users\\tie\\Desktop\\outen.txt"); byte byteIn[9]; byte byteOut[9]; byte byteWrite[256 * 1024]; memset(byteIn, 0, sizeof(byteIn)); memset(byteOut, 0, sizeof(byteOut)); memset(byteWrite, 0, sizeof(byteWrite)); size_t writeSize = 0; FILE *fp; fopen_s(&fp, "C:\\Users\\tie\\Desktop\\out.txt", "wb"); for (size_t i = 0; i < szGroupCount; i ++) { string strTmp = strHexContext.substr(0, 23); strHexContext = strHexContext.substr(24, strHexContext.size() - 1); if (strTmp.empty()) break; hexStringToBytes(strTmp, byteIn); m_poTea->encrypt(byteIn, byteOut); sprintf((char *)byteWrite + writeSize, "%s", byteOut); writeSize += 8; } fwrite(byteWrite, sizeof(unsigned char), writeSize, fp); fclose(fp); } void CryTool::testCry(const string & strFileName) { // testCryUseHex(strFileName); // // return; const string strAppend = "0"; CryFileTool::Data oData = CryFileTool::getData(strFileName, false); size_t szGroupCounts = oData.getSize() / 8; size_t szLostBitNum = oData.getSize() % 8; string strHex = bytesToHexString(oData.getBytes(), oData.getSize()); vector<byte> vectest(strHex.begin(), strHex.end()); testWriteHex(&vectest.front(), vectest.size(), "C:\\Users\\tie\\Desktop\\outen.txt"); FILE *fp; fopen_s(&fp, "C:\\Users\\tie\\Desktop\\out.txt", "wb"); byte byteIn[9]; byte byteOut[9]; byte byteWrite[256 * 1024]; memset(byteIn, 0, sizeof(byteIn)); memset(byteOut, 0, sizeof(byteOut)); memset(byteWrite, 0, sizeof(byteWrite)); size_t writeSize = 0; string strTitle = "["; char strCount[25]; sprintf(strCount, "%d", (8 - szLostBitNum)); strTitle.append(strCount); strTitle.append("]\r\n"); sprintf((char *)byteWrite + writeSize, "%s", strTitle.c_str()); writeSize += strTitle.size(); size_t szTest = 0; for (size_t i = 0; i < szGroupCounts; i ++) { byte * poByteHead = &oData.getBytes()[i * 8]; string strHexTemp = bytesToHexString(poByteHead, 8); memcpy(byteIn, poByteHead, 8); //printf("by in : %s\n", strHexTemp.c_str()); m_poTea->encrypt((byte*)strHexTemp.c_str(), byteOut); //printf("by out %s\n", byteOut); sprintf((char *)byteWrite + writeSize, "%s", byteOut); writeSize += 8; szTest += 8; } //need dual lost string strAppendTmp; for (size_t i = 0; i < (8 - szLostBitNum); i++) strAppendTmp.append(strAppend); fwrite(byteWrite, sizeof(unsigned char), writeSize, fp); fclose(fp); } void CryTool::testWriteHex(byte * poData, size_t szSize, const string & strFileName) { FILE *fp; fopen_s(&fp, strFileName.c_str(), "wb"); fwrite(poData, sizeof(unsigned char), szSize, fp); fclose(fp); } void CryTool::testDeCryUseHex() { const string strFileName = "C:\\Users\\tie\\Desktop\\out.txt"; static char acFinalDatas[1024 * 1024] = { 0 }; CryFileTool::Data oData = CryFileTool::getData(strFileName, false); unsigned char* pBuffer = oData.getBytes(); unsigned long size = oData.getSize(); if (size <= 0) return; string strHexString = bytesToHexString(pBuffer, size); strHexString.append(" "); size_t szGroupCounts = strHexString.size() / 24; byte byteIn[9] = {0}; byte byteOut[9] = { 0 }; size_t writeSize = 0; for (size_t i = 0; i < szGroupCounts; i++) { string strTmp = strHexString.substr(0, 23); strHexString = strHexString.substr(24, strHexString.size() - 1); if (strTmp.empty()) break; hexStringToBytes(strTmp, byteIn); m_poTea->decrypt(byteIn, byteOut); sprintf((char *)acFinalDatas + writeSize, "%s", byteOut); writeSize += 8; } string strContent; strContent.append((char*)acFinalDatas); strContent.empty(); string hex = bytesToHexString((unsigned char *)acFinalDatas, writeSize); //printf("%s", hex.c_str()); vector<byte> vecHex(hex.begin(), hex.end()); testWriteHex(&vecHex.front(), vecHex.size(), "C:\\Users\\tie\\Desktop\\outde.txt"); } void CryTool::testDeCry() { testDeCryUseHex(); return; const string strPreModel = "["; const string strLastMode = "]\r\n"; const string strFileName = "C:\\Users\\tie\\Desktop\\out.txt"; static char acFinalDatas[1024 * 1024] = {0}; CryFileTool::Data oData = CryFileTool::getData(strFileName, false); unsigned char* pBuffer = oData.getBytes(); unsigned long size = oData.getSize(); if (size <= 0) return; string strContext = ""; strContext.append((char *)pBuffer); size_t szEnd = 0; size_t szIDX = 0; while (true) { if (szIDX >= size || szEnd != 0) break; char cKey = pBuffer[szIDX]; if (strcmp("]", &cKey) != 0) { szEnd = szIDX; } szIDX++; } string strCount = strContext.substr(1, szEnd); if (strCount.empty()) return; int nLostCount = atoi(strCount.c_str()); string strFirstLine; strFirstLine.append(strPreModel); strFirstLine.append(strCount); strFirstLine.append(strLastMode); size_t szContentBegin = strFirstLine.size() - 1; strContext = strContext.substr(szContentBegin, strContext.size() - 1); size_t szGroupCounts = size / 8; byte byteIn[9]; byte byteOut[9]; size_t writeSize = 0; for (size_t i = 0; i < szGroupCounts; i ++) { byte * poByteHead = &pBuffer[i * 8]; memcpy(byteIn, poByteHead, 8); string strHexTemp = bytesToHexString(byteIn, 8); m_poTea->decrypt(byteIn, byteOut); sprintf((char *)acFinalDatas + writeSize, "%s", byteOut); writeSize += 8; } string hex = bytesToHexString((unsigned char *)acFinalDatas, writeSize); //printf("%s", hex.c_str()); vector<byte> vecHex(hex.begin(), hex.end()); testWriteHex(&vecHex.front(), vecHex.size(),"C:\\Users\\tie\\Desktop\\outde.txt"); } void CryTool::hexContentEncry(const string & strContent, byte * outData) { const string strAppendPart = " 00"; string strContentTmp = strContent; strContentTmp.append(" "); vector<string> vecHexGroups; int nPartcount = 24; int nContentSize = strContentTmp.size(); int nTotalCount = nContentSize / nPartcount; int nLostCount = nContentSize % nPartcount; for (int i = 0; i < nTotalCount; i++) { int nFrom = vecHexGroups.size() * nPartcount; string strTmp = strContentTmp.substr(nFrom > 0 ? nFrom : 0, nPartcount); vecHexGroups.push_back(strTmp); } if (nLostCount > 0) { int nFrom = vecHexGroups.size() * nPartcount; string strLost = strContentTmp.substr(nFrom > 0 ? nFrom : 0, nLostCount); strLost = strLost.substr(0, strLost.size() - 1); bool bCheck = true; while (bCheck) { strLost.append(strAppendPart); bCheck = !(strLost.size() >= 23); } vecHexGroups.push_back(strLost); } byte outPut[8]; byte outPut2[8]; vector<string> vecCryStrings; for (size_t i = 0; i < vecHexGroups.size(); i ++) { hexStringToBytes(vecHexGroups[i], outPut); m_poTea->encrypt(outPut, outPut2); string strTmp = bytesToHexString(outPut2, 8); vecCryStrings.push_back(strTmp); printf("=>%s \n", strTmp.c_str()); } vector<string> vecHexDecryString; for (size_t i = 0; i < vecCryStrings.size(); i ++) { hexStringToBytes(vecCryStrings[i], outPut); m_poTea->decrypt(outPut, outPut2); string strTmp = bytesToHexString(outPut2, 8); vecHexDecryString.push_back(strTmp); printf("--> %s \n", strTmp.c_str()); } string & strEnd = vecHexDecryString[vecHexDecryString.size() - 1]; if (strEnd.find(strAppendPart) != string::npos) { size_t delIDX = strEnd.find(strAppendPart); strEnd.erase(delIDX); } for (size_t i = 0; i < vecHexDecryString.size(); i++) printf("============== %s\n", vecHexDecryString[i].c_str()); string strHexTest; for (size_t i = 0; i < vecHexDecryString.size(); i ++) { strHexTest.append(vecHexDecryString[i]); } vector<unsigned char> vecTest(strHexTest.begin(), strHexTest.end()); byte by[1024] = {0}; hexStringToBytes(strHexTest, by); printf("\n::::::::::::::::::::: %s-\n", by); } void CryTool::partHexStringEncry(const string & strHexPart, byte * outData) { if (23 != strHexPart.size()) return; byte tmp[8]; hexStringToBytes(strHexPart, tmp); this->enCry(tmp, outData); } void CryTool::cryFileByName(const string & strFileName) { CryFileTool::Data oData = CryFileTool::getData(strFileName, false); unsigned char* pBuffer = oData.getBytes(); unsigned long size = oData.getSize(); string strHeString = bytesToHexString(pBuffer, size); this->hexContentEncry(strHeString, nullptr); }
然后是加密解密的工具类。 主要功能是读写文件。 重新实现了一下cocos2dx的Data类用来管理字符流。 还有各种字符转换的工具函数。
转载请注明链接 : http://www.cnblogs.com/bluen/p/4453354.html
头文件
#ifndef __CRYFILEUTILS_H__ #define __CRYFILEUTILS_H__ #include <string> #include <cmath> #include <cstdlib> using namespace std; namespace CryFileTool { class Data { public: static const Data Null; Data(); Data(const Data& other); Data(Data&& other); ~Data(); // Assignment operator Data& operator= (const Data& other); Data& operator= (Data&& other); /** * @js NA * @lua NA */ unsigned char* getBytes() const; /** * @js NA * @lua NA */ size_t getSize() const; /** Copies the buffer pointer and its size. * @note This method will copy the whole buffer. * Developer should free the pointer after invoking this method. * @see Data::fastSet */ void copy(unsigned char* bytes, const size_t size); /** Fast set the buffer pointer and its size. Please use it carefully. * @param bytes The buffer pointer, note that it have to be allocated by 'malloc' or 'calloc', * since in the destructor of Data, the buffer will be deleted by 'free'. * @note 1. This method will move the ownship of 'bytes'pointer to Data, * 2. The pointer should not be used outside after it was passed to this method. * @see Data::copy */ void fastSet(unsigned char* bytes, const size_t size); /** Clears data, free buffer and reset data size */ void clear(); /** Check whether the data is null. */ bool isNull() const; private: void move(Data& other); private: unsigned char* _bytes; size_t _size; }; static Data getData(const std::string& filename, bool forString) { if (filename.empty()) { return Data::Null; } Data ret; unsigned char* buffer = nullptr; size_t size = 0; size_t readsize; const char* mode = nullptr; if (forString) mode = "rt"; else mode = "rb"; do { // Read the file from hardware std::string fullPath = filename; FILE *fp = nullptr; fopen_s(&fp, fullPath.c_str(), mode); fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); if (forString) { buffer = (unsigned char*)malloc(sizeof(unsigned char)* (size + 1)); buffer[size] = '\0'; } else { buffer = (unsigned char*)malloc(sizeof(unsigned char)* size); } readsize = fread(buffer, sizeof(unsigned char), size, fp); fclose(fp); std::string::size_type pos = filename.rfind('.'); std::string ext = filename.substr(pos == std::string::npos ? filename.length() : pos + 1); if (forString) { buffer[readsize] = '\0'; } } while (0); if (nullptr == buffer || 0 == readsize) { std::string msg = "Get data from file("; msg.append(filename).append(") failed!"); } else { ret.fastSet(buffer, readsize); } return ret; } }; #endif
实现文件
#include "CryFileUtils.h" namespace CryFileTool { const Data Data::Null; Data::Data() : _bytes(nullptr), _size(0) { //pr("In the empty constructor of Data."); } Data::Data(Data&& other) : _bytes(nullptr), _size(0) { //CCLOGINFO("In the move constructor of Data."); move(other); } Data::Data(const Data& other) : _bytes(nullptr), _size(0) { //CCLOGINFO("In the copy constructor of Data."); copy(other._bytes, other._size); } Data::~Data() { //CCLOGINFO("deallocing Data: %p", this); clear(); } Data& Data::operator= (const Data& other) { //CCLOGINFO("In the copy assignment of Data."); copy(other._bytes, other._size); return *this; } Data& Data::operator= (Data&& other) { //CCLOGINFO("In the move assignment of Data."); move(other); return *this; } void Data::move(Data& other) { _bytes = other._bytes; _size = other._size; other._bytes = nullptr; other._size = 0; } bool Data::isNull() const { return (_bytes == nullptr || _size == 0); } unsigned char* Data::getBytes() const { return _bytes; } size_t Data::getSize() const { return _size; } void Data::copy(unsigned char* bytes, const size_t size) { clear(); if (size > 0) { _size = size; _bytes = (unsigned char*)malloc(sizeof(unsigned char)* _size); memcpy(_bytes, bytes, _size); } } void Data::fastSet(unsigned char* bytes, const size_t size) { _bytes = bytes; _size = size; } void Data::clear() { free(_bytes); _bytes = nullptr; _size = 0; } };
。
转载请注明链接 : http://www.cnblogs.com/bluen/p/4453354.html
就酱。有问题或者建议可以留言讨论。