C语言实现无规律数据加密、解密功能
在网络传输重要信息或存储重要文件信息时,大部分会对数据加密,保证数据的安全性。互联网上流行的可逆加密方式对数据的安全性没有保证,便自己写了一套安全性极高加密、解密方法。
方法的实现方式及特点:
1.采用指定单个字节加密转换(转换形式为ascll码表中0-128的形式,由1个字节拆分为三个字节,下面说明拆分方式);
2.采用数组中随机数据减指定加密字节(比如当前数据ascll码为121,当前数组中的数据为222,结果为222-121=101,当然这个只是参考实例);
3.采用随机指定数组方式(如果需要用到无规律加密方式,可以通过随机指定数组方式进行加密);
4.指定很大的数据加密格式(比如使用1-2048字节中任意长度为一次的加密比例,大量数据分为多次加密);
5.多次加密数据时,第一次加密数据生成数据头与加密信息,之后只生成加密信息(数据头包含使用的加密数组(比如数组1、数组2、等…,)和加密字节长度,解析数据时将会根据数据头获取到这些信息);
6.加密字节为跳序形式(比如指定加密1,3,5字节或者指定为别的字节调序形式,只需简单改些代码就能实现);
指定一个字节加密后拆分为三个字节表示为:
①第一个字节为随机数组中的随机数据(比如数组有8个数据,第一个字节范围0-7作为标记,用来解密使用);
②第二个字节为加密后的数据拆分的一部分(小于128用来对上ascll码表);
③第三个字节为采用的拆分格式(解密使用)。
下面贴上加密使用的数组:
//数组中的任意数据都可以修改为1-255之间,末尾数据为0防止数组越界
unsignedcharData1[]={255,210,208,179,168,199,202,189,0};
unsignedcharData2[]={166,207,205,196,191,190,163,180,0};
unsignedcharData3[]={155,197,186,172,228,226,219,239,0};
unsignedcharData4[]={188,229,192,254,252,212,230,217,0};
unsignedcharData5[]={229,206,212,224,253,211,181,207,0};
目前代码中使用的是这5个数组,需要更大的随机性可以通过简单修改代码,写入更多的数组,数组中的数据在1-255(不建议写0,字符串中0为结尾)。
数据头定义格式:
数据头1-3字节为“LKY”用来校验加密后的数据,如果数据中不存在,将不处理数据;
数据头4-128字节为校验信息段,如果校验不正确,将不处理数据;
数据头129-133字节为使用的指定数组进行加密(目前最大可以指定5个数组,同时使用5个数组进行对指定直接加密处理,修改代码可以增加更多的数组);
数据头134-256字节为补数据;
数据头257-260字节为指定的加密长度(加密长度为1-2048);
数据头261-512字节为补数据;
数据头的总长度为512个字节。
下面贴上.h文件(其中包括任意格式文件的加密、解密函数):
#includestructFileData { CStringFilename; LPVOID_this; boolbCover; }; //数据加密解密类 classDataOperation { public: DataOperation(); virtual~DataOperation(); /*****************************加密部分***************************/ //设置加密数据(传入1表示使用unsignedcharData1[]={255,210,208,179,168,199,202,189,193,0}数组加密)传入类型1-5, //如果传入数据超过5次,不再记录 boolSetEncryptionData(intnCount); //设备每一次加密的数据长度值为0-2048,默认使用2048 boolSetEncryptionLen(intnLen); //加密数据函数 //返回加密完成的函数 //如果传入的数据超过设置每一次加密的数据长度,将会采用设置的数据长度 //第一次调用会生成512字节数据头与加密后的数据一起返回(比如需要加密3048个字节数据,第一次调用函数返回数据头和2048加密后的数据,第二次调用返回剩下1000个字节加密后的数据) char*EncryptionData(char*SrcData,int&nDataLen); //加密文件 //参数一文件完整路径加名称 //参数二true为覆盖文件false为创建文件名加_Temp的新文件 boolEncryptionFile(CStringFilename,boolbCover); /**********************************************/ /******************解密部分*****************************/ //解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等) intDecryptionHead(char*SrcData); //解密数据(传入加密后的数据以及数据长度,不要带数据头信息) //比如解密3048字节长度数据,去掉数据512个字节数据(数据头信息),从513字节开始为需要解析的数据 //nDataLen为解析数据头返回的每次需要传入的数据长度 char*DecryptionData(constchar*SrcData,int&nDataLen); //解密文件 boolDecryptionFile(CStringFilename,boolbCover); /************************************************/ private: //加密数据计算函数 char*EncryptionData_(char*SrcData,int&nDataLen,char*HeadData=0); //指定字节进行加密运算 unsignedchar*Encryption_Operation(std::vector VData,unsignedcharSrcData[]); //获取指定的加密数组 unsignedchar*GetData_Operation(intnVal); //根据指定加密长度获取解密长度 intGetDecryptionDataLen(intnDataLen); //指定字节进行解密运算 unsignedchar*Decryption_Operation(unsignedchar*VData[],unsignedcharSrcData[],intnVDataLen); private: //保存需要使用的加密数据(只在加密数据时使用,解密时自动根据数据头信息获取加密数据) charm_EncryptionData[6]; //保存需要使用的解密数据 charm_DecryptionData[6]; // intm_EncryptionDataLen; // intm_DecryptionDataLen; // boolm_bValidHead; };
下面贴上.cpp文件:
#include"stdafx.h"
#include"Operation.h"
unsignedcharData1[]={255,210,208,179,168,199,202,189,0};
unsignedcharData2[]={166,207,205,196,191,190,163,180,0};
unsignedcharData3[]={155,197,186,172,228,226,219,239,0};
unsignedcharData4[]={188,229,192,254,252,212,230,217,0};
unsignedcharData5[]={229,206,212,224,253,211,181,207,0};
//数组的长度
intDataLen=8;
//获取数组
#defineGetData(nVal)\
Data##nVal;
DataOperation::DataOperation():m_EncryptionDataLen(2048),m_bValidHead(false),m_DecryptionDataLen(0)
{
memset(m_EncryptionData,0,sizeof(m_EncryptionData));
memset(m_DecryptionData,0,sizeof(m_DecryptionData));
SetEncryptionData(2);
SetEncryptionData(1);
}
DataOperation::~DataOperation()
{
}
//如果传入数据超过5次,不再记录
boolDataOperation::SetEncryptionData(intnCount)
{
intnLen=strlen(m_EncryptionData);
if(5<=nLen)
returnfalse;
m_EncryptionData[nLen]=nCount;
returntrue;
}
//设备每一次加密的数据长度值为0-2048,默认使用2048
boolDataOperation::SetEncryptionLen(intnLen)
{
if(0>=nLen||2048VData;
for(intilen=0;ilenVData,unsignedcharSrcData[])
{
staticULONG64StrEncryptionVal=0;
//第一个字节标记加密数组的字节位置
SrcData[0]=(StrEncryptionVal%DataLen+'0');
for(autoit=VData.begin();it!=VData.end();it++)
{
unsignedchar*data=*it;
SrcData[1]=(data[SrcData[0]-'0'])-SrcData[1];
}
++StrEncryptionVal;
returnSrcData;
}
//获取指定的加密数组
unsignedchar*DataOperation::GetData_Operation(intnVal)
{
switch(nVal)
{
case1:
{
returnGetData(1);
}
break;
case2:
{
returnGetData(2);
}
break;
case3:
{
returnGetData(3);
}
break;
case4:
{
returnGetData(4);
}
break;
case5:
{
returnGetData(5);
}
break;
}
return0;
}
//解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等)
intDataOperation::DecryptionHead(char*SrcData)
{
if(0==SrcData||512>strlen(SrcData))
return0;
charpSrcData[513]={0};
memcpy(pSrcData,SrcData,512);
if(pSrcData[0]!='L'||pSrcData[1]!='K'||pSrcData[2]!='Y')
return0;
//前128位校验数据头信息
inti=127;
for(;i>3;i--)
pSrcData[i-1]=((pSrcData[i]+i)%128-pSrcData[i-1]-1);
if(pSrcData[i-1]!='Y')
return0;
//129-134为使用的加密数据
i=128;
intii=0;
memset(m_DecryptionData,0,sizeof(m_DecryptionData));
for(;i<133;i++)
{
if('0'==pSrcData[i])
{
continue;
}
else
{
m_DecryptionData[ii++]=pSrcData[i];
}
}
//257-261为加密长度
charEncryptionDataLen[5]={0};
ii=0;
i=256;
for(;i<260;i++)
{
if(pSrcData[i]=='99')
{
continue;
}
else
{
EncryptionDataLen[ii++]=pSrcData[i];
}
}
m_EncryptionDataLen=atoi(EncryptionDataLen);
m_DecryptionDataLen=GetDecryptionDataLen(m_EncryptionDataLen);
returnm_DecryptionDataLen;
}
//根据指定加密长度获取解密长度
intDataOperation::GetDecryptionDataLen(intnDataLen)
{
if(0>=nDataLen)
return0;
intnIndex=0;
for(inti=0;i=nDataLen)
return0;
charData[2048+100]={0};
intnIndex=0;
intnOffset=0,nLeft=0,nCurrent=0;
intnLen=(m_DecryptionDataLen<=nDataLen?m_DecryptionDataLen:nDataLen);
//获取解密
intnDecryptionDataLen=strlen(m_DecryptionData);
unsignedchar*VData[10]={0};
intnVDataLen=0;
for(intiLen=nDecryptionDataLen;iLen>0;iLen--)
{
intnVal=m_DecryptionData[iLen-1];
unsignedchar*DataArray=GetData_Operation(nVal);
VData[nVDataLen++]=DataArray;
}
inti=0;
//开始加密数据
for(;i=nDataLen)
{
break;
}
//拷贝没有加密的数据
if(0=nFileLen)
returnfalse;
CStringFilename2(Filename.Mid(0,Filename.ReverseFind(_T('.'))));
Filename2.AppendFormat(_T("_Temp%s"),Filename.Mid(Filename.ReverseFind(_T('.')),
Filename.GetLength()-Filename.ReverseFind(_T('.'))));
if(!file2.Open(Filename2,CFile::modeCreate|CFile::modeWrite))
returnfalse;
charStrData[2048+100]={0};
intnDataLen=0;
file1.Read(StrData,512);
//解密数据头
intnDecryptionLen=DecryptionHead(StrData);
if(0>=nDecryptionLen)
returnfalse;
nFileLen-=512;
while(0
下面说下具体函数用法:
//设置加密数据(传入1表示使用unsignedcharData1[]={255,210,208,179,168,199,202,189,193,0}数组加密)传入类型1-5,
//如果传入数据超过5次,不再记录
//这个函数需要在加密函数使用之前调用,默认采用2、1数组加密
boolSetEncryptionData(intnCount);
//设置每一次加密的数据长度值为0-2048,默认使用2048
boolSetEncryptionLen(intnLen);
//加密数据函数
//返回加密完成的函数
//如果传入的数据超过设置每一次加密的数据长度,将会采用设置的数据长度
//第一次调用会生成512字节数据头与加密后的数据一起返回(比如需要加密3048个字节数据,第一次调用函数返回数据头和2048加密后的数据,第二次调用返回剩下1000个字节加密后的数据)
char*EncryptionData(char*SrcData,int&nDataLen);
//加密文件
//参数一文件完整路径加名称
//参数二true为覆盖文件false为创建文件名加_Temp的新文件
boolEncryptionFile(CStringFilename,boolbCover);
//解析数据头信息,返回每一次解密需要传入的数据长度(使用加密后的数据前512字节为数据头信息传入函数获取到加密数据以及加密的数据长度等)
intDecryptionHead(char*SrcData);
//解密数据(传入加密后的数据以及数据长度,不要带数据头信息)
//比如解密3048字节长度数据,去掉数据512个字节数据(数据头信息),从513字节开始为需要解析的数据
//nDataLen为解析数据头返回的每次需要传入的数据长度
char*DecryptionData(constchar*SrcData,int&nDataLen);
//解密文件
//参数一文件完整路径加名称
//参数二true为覆盖文件false为创建文件名加_Temp的新文件
boolDecryptionFile(CStringFilename,boolbCover);
函数使用方式参考加密文件和解密文件函数,工程下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。