• 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 << " 将文件或者文件夹拖入下方 :" << 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;
    };
    View Code

    实现文件的单例管理部分。

    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, "
    ");
            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
    ", 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, "
    ");
            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
    ", 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, "
    ");
            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
    ", 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("]
    ");
        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
    ", strHexTemp.c_str());
            m_poTea->encrypt((byte*)strHexTemp.c_str(), byteOut);
            //printf("by out  %s
    ", 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 = "]
    ";
    
        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 
    ", 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 
    ", 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
    ", 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("
    ::::::::::::::::::::: %s-
    ", 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);
    
    }
    View Code

    然后是加密解密的工具类。 主要功能是读写文件。 重新实现了一下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] = '';
                }
                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] = '';
                }
            } 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
    View Code

    实现文件

    #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;
        }
    
    
    };
    View Code

     转载请注明链接 : http://www.cnblogs.com/bluen/p/4453354.html

    就酱。有问题或者建议可以留言讨论。 

  • 相关阅读:
    VBA_headers_mapping
    pandas_知识总结_基础
    python_super()及继承顺序
    python_端口扫描
    python_socket登陆验证_明文
    python_sys.argv的使用
    python_os_shutil_获取文件夹下所有文件的大小
    python_面向对象_组合
    魔术球问题 【网络流24题】【建图技巧】
    牛客&科大讯飞杯&SHU、L动物森友会【二分】【网络流】
  • 原文地址:https://www.cnblogs.com/bluen/p/4453354.html
Copyright © 2020-2023  润新知