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;
};
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, "\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);

}
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] = '\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
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

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

posted @ 2015-04-24 14:21  bluen  阅读(5878)  评论(1编辑  收藏  举报