中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言實現無規律數據加密、解密功能

發布時間:2020-08-19 15:36:29 來源:腳本之家 閱讀:299 作者:大昱 欄目:編程語言

在網絡傳輸重要信息或存儲重要文件信息時,大部分會對數據加密,保證數據的安全性。互聯網上流行的可逆加密方式對數據的安全性沒有保證,便自己寫了一套安全性極高加密、解密方法。

方法的實現方式及特點:

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防止數組越界
unsigned char Data1[] ={255,210,208,179,168,199,202,189,0};
unsigned char Data2[] ={166,207,205,196,191,190,163,180,0};
unsigned char Data3[] ={155,197,186,172,228,226,219,239,0};
unsigned char Data4[] ={188,229,192,254,252,212,230,217,0};
unsigned char Data5[] ={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文件(其中包括任意格式文件的加密、解密函數):

#include <vector>

struct FileData
{
 CString Filename;
 LPVOID _this;
 bool bCover;
};

//數據加密解密類
class DataOperation
{
public:
 DataOperation();
 virtual ~DataOperation();
/***************************** 加密部分 ***************************/
 //設置加密數據(傳入1表示使用unsigned char Data1[] ={255,210,208,179,168,199,202,189,193,0}數組加密)傳入類型1-5,
 //如果傳入數據超過5次,不再記錄
 bool SetEncryptionData(int nCount);
 //設備每一次加密的數據長度值為0-2048,默認使用2048
 bool SetEncryptionLen(int nLen);
 //加密數據函數
 //返回加密完成的函數
 //如果傳入的數據超過設置每一次加密的數據長度,將會采用設置的數據長度
 //第一次調用會生成512字節數據頭與加密后的數據一起返回(比如需要加密3048個字節數據,第一次調用函數返回數據頭和2048加密后的數據,第二次調用返回剩下1000個字節加密后的數據)
 char *EncryptionData(char * SrcData,int & nDataLen);
 //加密文件
 //參數一文件完整路徑加名稱
 //參數二 true為覆蓋文件 false為創建文件名加_Temp的新文件
 bool EncryptionFile(CString Filename,bool bCover);
/**********************************************/

/****************** 解密部分 *****************************/
 //解析數據頭信息,返回每一次解密需要傳入的數據長度(使用加密后的數據前512字節為數據頭信息傳入函數獲取到加密數據以及加密的數據長度等)
 int DecryptionHead(char * SrcData);
 //解密數據(傳入加密后的數據以及數據長度,不要帶數據頭信息)
 //比如解密3048字節長度數據,去掉數據512個字節數據(數據頭信息),從513字節開始為需要解析的數據
 //nDataLen 為解析數據頭返回的每次需要傳入的數據長度
 char *DecryptionData(const char * SrcData,int & nDataLen);
 //解密文件
 bool DecryptionFile(CString Filename,bool bCover);
/************************************************/
private:
 //加密數據計算函數
 char *EncryptionData_(char * SrcData,int & nDataLen,char *HeadData = 0);
 //指定字節進行加密運算
 unsigned char *Encryption_Operation(std::vector<unsigned char *> VData,unsigned char SrcData[]);
 //獲取指定的加密數組
 unsigned char * GetData_Operation(int nVal);
 //根據指定加密長度獲取解密長度
 int GetDecryptionDataLen(int nDataLen);
 //指定字節進行解密運算
 unsigned char *Decryption_Operation(unsigned char * VData[],unsigned char SrcData[],int nVDataLen);
private:
 //保存需要使用的加密數據(只在加密數據時使用,解密時自動根據數據頭信息獲取加密數據)
 char m_EncryptionData[6];
 //保存需要使用的解密數據
 char m_DecryptionData[6];
 //
 int m_EncryptionDataLen;
 //
 int m_DecryptionDataLen;
 //
 bool m_bValidHead;
};

下面貼上.cpp文件:

#include "stdafx.h"
#include "Operation.h"

unsigned char Data1[] ={255,210,208,179,168,199,202,189,0};
unsigned char Data2[] ={166,207,205,196,191,190,163,180,0};
unsigned char Data3[] ={155,197,186,172,228,226,219,239,0};
unsigned char Data4[] ={188,229,192,254,252,212,230,217,0};
unsigned char Data5[] ={229,206,212,224,253,211,181,207,0};
//數組的長度
int DataLen = 8;
//獲取數組
#define GetData(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次,不再記錄
bool DataOperation::SetEncryptionData(int nCount)
{
 int nLen = strlen(m_EncryptionData);
 if (5 <= nLen)
 return false;
 m_EncryptionData[nLen] = nCount;
 return true;
}

//設備每一次加密的數據長度值為0-2048,默認使用2048
bool DataOperation::SetEncryptionLen(int nLen)
{
 if (0 >= nLen || 2048 < nLen)
 return false;
 m_EncryptionDataLen = nLen;
 return true;
}

//加密數據函數
char * DataOperation::EncryptionData(char * SrcData,int & nDataLen)
{
 if (0 == SrcData)
 return 0;
 if (!m_bValidHead)
 {
 //首先生出數據頭,然后與數據合并
 char DataHead[513] = {0};
 int nInIdex = strlen("LKY");
 memcpy(DataHead,"LKY",nInIdex);
 //前128位校驗數據頭信息
 for (int i = 3;i < 128;i++)
 {
  DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
 }
 int ii = 0;
 //129-133為使用的加密數據
 for (int i = 128;i < 133;i++)
 {

  if (0 == m_EncryptionData[ii])
  {
  DataHead[i] = '0';
  }
  else
  {
  DataHead[i] = m_EncryptionData[ii];
  }
  ++ii;
 }
 //134-256為補數據
 for (int i = 133;i < 256;i++)
 {
  DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
 }
 //257-261為加密長度
 char EncryptionDataLen[5] = {0};
 itoa(m_EncryptionDataLen,EncryptionDataLen,10);
 ii = 0;
 for (int i = 256;i < 260;i++)
 {
  if (0 == EncryptionDataLen[ii])
  {
  DataHead[i] = '99';
  }
  else
  {
  DataHead[i] = EncryptionDataLen[ii];
  }
  ++ii;
 }
 //261-512為補數據
 for (int i = 260;i < 512;i++)
 {
  DataHead[i] = ((DataHead[i - 1] + i)%128 + 1);
 }
 m_bValidHead = true;
 return EncryptionData_(SrcData,nDataLen,DataHead);
 }
 return EncryptionData_(SrcData,nDataLen);
}


//加密數據計算函數
char *DataOperation::EncryptionData_(char * SrcData,int & nLen,char *HeadData)
{
 char pStrData[2048 + 513 + 26] = {0};
 int nIndex = 0;
 if (0 != HeadData)
 {
 memcpy(pStrData,HeadData,512);
 nIndex += 512;
 }
 int nOffset = 0,nLeft = 0;
 int nDataLen = (m_EncryptionDataLen <= nLen ? m_EncryptionDataLen : nLen);
 //獲取加密數組
 std::vector<unsigned char *>VData;
 for(int ilen = 0;ilen < strlen(m_EncryptionData);ilen++)
 {
 int nVal = m_EncryptionData[ilen];
 unsigned char * DataArray = GetData_Operation(nVal);
 VData.push_back(DataArray);
 }
 int i = 0;
 //開始加密數據
 for (;i < nDataLen;(i = i * 2 + 1))
 {
 //拷貝沒有加密的數據
 if (0 < i - nLeft)
 {
  memcpy(pStrData + nIndex,SrcData + nLeft,i - nLeft);
  nIndex += i - nLeft;
 }

 unsigned char StrTemp[4] = {0,SrcData[i],0,0};
 Encryption_Operation(VData,StrTemp);

 if(128 <= StrTemp[1])
 {
  StrTemp[1] = StrTemp[1] - 127;
  StrTemp[2] = 127;
 }
 else if (0 == StrTemp[1])
 {
  StrTemp[1] = '0';
  StrTemp[2] = '0';
 }
 else
 {
  StrTemp[1] = 128 - StrTemp[1];
  StrTemp[2] = '1';
 }

 //拷貝轉換過的數據
 memcpy(pStrData + nIndex,StrTemp,strlen((char *)StrTemp));
 nIndex += strlen((char *)StrTemp);
 nLeft = i + 1;
 }

 if (nLeft < nDataLen && 0 != nIndex)
 {
 memcpy(pStrData + nIndex,SrcData + nLeft,nDataLen - nLeft);
 nIndex += nDataLen - nLeft;
 }
 else if (0 == nIndex)
 {
 nLen = nDataLen;
 return pStrData;
 }
 nLen = nIndex;
 return pStrData;
}

//指定字節進行加密運算
unsigned char *DataOperation::Encryption_Operation(std::vector<unsigned char *> VData,unsigned char SrcData[])
{

 static ULONG64 StrEncryptionVal = 0;
 //第一個字節標記加密數組的字節位置
 SrcData[0] = (StrEncryptionVal % DataLen + '0');
 for (auto it = VData.begin();it != VData.end();it++)
 {
 unsigned char * data = *it;
 SrcData[1] = (data[SrcData[0] - '0']) - SrcData[1];
 }
 ++StrEncryptionVal;
 return SrcData;
}

//獲取指定的加密數組
unsigned char * DataOperation::GetData_Operation(int nVal)
{
 switch (nVal)
 {
 case 1:
 {
  return GetData(1);
 }
 break;
 case 2:
 {
  return GetData(2);
 }
 break;
 case 3:
 {
  return GetData(3);
 }
 break;
 case 4:
 {
  return GetData(4);
 }
 break;
 case 5:
 {
  return GetData(5);
 }
 break;
 }
 return 0;
}

//解析數據頭信息,返回每一次解密需要傳入的數據長度(使用加密后的數據前512字節為數據頭信息傳入函數獲取到加密數據以及加密的數據長度等)
int DataOperation::DecryptionHead(char * SrcData)
{
 if (0 == SrcData || 512 > strlen(SrcData))
 return 0;
 char pSrcData[513] = {0};
 memcpy(pSrcData,SrcData,512);
 if (pSrcData[0] != 'L' || pSrcData[1] != 'K' || pSrcData[2] != 'Y')
 return 0;
 //前128位校驗數據頭信息
 int i = 127;
 for (;i > 3;i--)
 pSrcData[i - 1] = ((pSrcData[i] + i)%128 - pSrcData[i - 1] - 1);
 if (pSrcData[i - 1] != 'Y')
 return 0;

 //129-134為使用的加密數據
 i = 128;
 int ii = 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為加密長度
 char EncryptionDataLen[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);
 return m_DecryptionDataLen;
}

//根據指定加密長度獲取解密長度
int DataOperation::GetDecryptionDataLen(int nDataLen)
{
 if (0 >= nDataLen)
 return 0;
 int nIndex = 0;
 for (int i = 0;i < nDataLen;(i = i * 2 + 1))
 {
 nIndex += 2;
 }
 return nDataLen + nIndex;
}

//解密數據(傳入加密后的數據以及數據長度,不要帶數據頭信息)
char *DataOperation::DecryptionData(const char * SrcData,int & nDataLen)
{
 if (0 == SrcData || 0 >= nDataLen)
 return 0;

 char Data[2048 + 100] = {0};
 int nIndex = 0;
 int nOffset = 0,nLeft = 0,nCurrent = 0;
 int nLen = (m_DecryptionDataLen <= nDataLen ? m_DecryptionDataLen : nDataLen);
 //獲取解密
 int nDecryptionDataLen = strlen(m_DecryptionData);
 unsigned char *VData[10] = {0};
 int nVDataLen = 0;
 for(int iLen = nDecryptionDataLen;iLen > 0;iLen--)
 {
 int nVal = m_DecryptionData[iLen - 1];
 unsigned char * DataArray = GetData_Operation(nVal);
 VData[nVDataLen++] = DataArray;
 }
 int i = 0;
 //開始加密數據
 for (;i < nLen;(i = i * 2 + 1))
 {
 nCurrent = i + nOffset;
 if (nCurrent >= nDataLen)
 {
  break;
 }

 //拷貝沒有加密的數據
 if (0 < nCurrent - nLeft)
 {
  memcpy(Data + nIndex,SrcData + nLeft,nCurrent - nLeft);
  nIndex += (nCurrent - nLeft);
 }

 unsigned char StrTemp[4] = {SrcData[nCurrent],SrcData[nCurrent + 1],SrcData[nCurrent + 2],0};

 if (127 == StrTemp[2])
 {
  StrTemp[1] = StrTemp[1] + 127;
  StrTemp[2] = 0;
 }
 else if ('1' == StrTemp[2])
 {
  StrTemp[1] = 128 - StrTemp[1];
  StrTemp[2] = 0;
 }
 else if ('0' == StrTemp[2])
 {
  StrTemp[1] = 0;
  StrTemp[2] = 0;
 }
 else
 {
  StrTemp[2] = 0;
 }

 Decryption_Operation(VData,StrTemp,nDecryptionDataLen);
 //拷貝轉換過的數據
 memcpy(Data + nIndex,StrTemp + 1,1);
 nIndex += 1;
 nOffset += 2;
 nLeft = i + nOffset + 1;
 }
 if (nLeft < nLen && 0 != nIndex)
 {
 memcpy(Data + nIndex,SrcData + nLeft,nLen - nLeft);
 nIndex += nLen - nLeft;
 }
 else if (0 == nIndex)
 {
 return Data;
 }

 nDataLen = nIndex;
 return Data;
}

//指定字節進行解密運算
unsigned char *DataOperation::Decryption_Operation(unsigned char * VData[],unsigned char SrcData[],int nVDataLen)
{
 for (int i = 0;i < nVDataLen;i++)
 {
 unsigned char * data = VData[i];
 SrcData[1] = (data[SrcData[0] - '0']) - SrcData[1];
 }
 return SrcData;
}


//加密文件
bool DataOperation::EncryptionFile(CString Filename,bool bCover)
{
 //增加隨機加密 默認使用2,1數組
 SetEncryptionData(5);
 SetEncryptionData(4);

 if (Filename.IsEmpty())
 return false;
 CFile file1,file2;
 if (!file1.Open(Filename,CFile::modeRead))

 return false;
 ULONG64 nFileLen = file1.GetLength();
 if (0 == nFileLen)
 return false;

 CString Filename2(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))
 return false;
 char StrData[4096] = {0};
 int nDataLen = 0;
 while (0 < nFileLen)
 {
 if (2048 <= nFileLen)
 {
  file1.Read(StrData,2048);
  nDataLen = 2048;
  char *WriteFile = EncryptionData(StrData,nDataLen);
  file2.Write(WriteFile,nDataLen);
  nFileLen -= 2048;
 }
 else
 {
  file1.Read(StrData,nFileLen);
  nDataLen = nFileLen;
  char *WriteFile = EncryptionData(StrData,nDataLen);
  file2.Write(WriteFile,nDataLen);
  nFileLen -= nFileLen;
  break;
 }
 }
 file1.Close();
 file2.Close();
 if (bCover)
 {
 USES_CONVERSION;
 //覆蓋本地文件
 int nResult = remove(T2A(Filename));
 nResult = rename(T2A(Filename2),T2A(Filename));
 }
 return true;
}

//解密文件
bool DataOperation::DecryptionFile(CString Filename,bool bCover)
{
 if (Filename.IsEmpty())
 return false;
 CFile file1,file2;
 if (!file1.Open(Filename,CFile::modeRead))
 return false;
 ULONG64 nFileLen = file1.GetLength();
 if (512 >= nFileLen)
 return false;

 CString Filename2(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))
 return false;
 char StrData[2048 + 100] = {0};
 int nDataLen = 0;
 file1.Read(StrData,512);
 //解密數據頭
 int nDecryptionLen = DecryptionHead(StrData);
 if (0 >= nDecryptionLen)
 return false;
 nFileLen -= 512;


 while (0 < nFileLen)
 {

 if (nDecryptionLen <= nFileLen)
 {

  nDataLen = nDecryptionLen;
  file1.Read(StrData,nDataLen);
  char *WriteFile = DecryptionData(StrData,nDataLen);
  memset(StrData,0,strlen(StrData));
  memcpy(StrData,WriteFile,nDataLen);
  file2.Write(StrData,nDataLen);
  nFileLen -= nDecryptionLen;
 }
 else
 {
  nDataLen = nFileLen;
  file1.Read(StrData,nFileLen);
  char *WriteFile = DecryptionData(StrData,nDataLen);
  memset(StrData,0,strlen(StrData));
  memcpy(StrData,WriteFile,nDataLen);
  file2.Write(StrData,nDataLen);
  nFileLen -= nFileLen;
  break;
 }
 }
 file1.Close();
 file2.Close();
 if (bCover)
 {
 USES_CONVERSION;
 //覆蓋本地文件
 int nResult = remove(T2A(Filename));
 nResult = rename(T2A(Filename2),T2A(Filename));
 }

 return true;
}

下面說下具體函數用法:

//設置加密數據(傳入1表示使用unsigned char Data1[] ={255,210,208,179,168,199,202,189,193,0}數組加密)傳入類型1-5,
//如果傳入數據超過5次,不再記錄
//這個函數需要在加密函數使用之前調用,默認采用2、1數組加密
bool SetEncryptionData(int nCount);


//設置每一次加密的數據長度值為0-2048,默認使用2048
bool SetEncryptionLen(int nLen);


//加密數據函數
//返回加密完成的函數
//如果傳入的數據超過設置每一次加密的數據長度,將會采用設置的數據長度
//第一次調用會生成512字節數據頭與加密后的數據一起返回(比如需要加密3048個字節數據,第一次調用函數返回數據頭和2048加密后的數據,第二次調用返回剩下1000個字節加密后的數據)
char *EncryptionData(char * SrcData,int & nDataLen);


//加密文件
//參數一文件完整路徑加名稱
//參數二 true為覆蓋文件 false為創建文件名加_Temp的新文件
bool EncryptionFile(CString Filename,bool bCover);


//解析數據頭信息,返回每一次解密需要傳入的數據長度(使用加密后的數據前512字節為數據頭信息傳入函數獲取到加密數據以及加密的數據長度等)
int DecryptionHead(char * SrcData);


//解密數據(傳入加密后的數據以及數據長度,不要帶數據頭信息)
//比如解密3048字節長度數據,去掉數據512個字節數據(數據頭信息),從513字節開始為需要解析的數據
//nDataLen 為解析數據頭返回的每次需要傳入的數據長度
char *DecryptionData(const char * SrcData,int & nDataLen);


//解密文件
//參數一文件完整路徑加名稱
//參數二 true為覆蓋文件 false為創建文件名加_Temp的新文件
bool DecryptionFile(CString Filename,bool bCover);

函數使用方式參考加密文件和解密文件函數,工程下載地址

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿拉善左旗| 定南县| 运城市| 迁西县| 高碑店市| 连江县| 琼海市| 宜城市| 越西县| 金乡县| 哈密市| 蒙城县| 镇宁| 南部县| 县级市| 招远市| 祥云县| 无锡市| 凯里市| 多伦县| 肥城市| 湖北省| 曲松县| 乌鲁木齐县| 枣庄市| 蒙自县| 宜良县| 宕昌县| 永平县| 榕江县| 应城市| 新安县| 东平县| 宣化县| 交城县| 中西区| 甘孜县| 江都市| 桃园县| 松溪县| 阜新|