⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blowfish.cpp

📁 一些加密算法的介绍,可对文件或字符串加密
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			x <<= 8;
			x |= *(p++);
			iCount++;
			if(iCount == m_keylength)
			{
				//All bytes used, so recycle bytes 
				iCount = 0;
				p = reinterpret_cast<unsigned char*>(&key[0]);
			}
		}
		m_auiP[i] ^= x;
	}
	//Reflect P and S boxes through the evolving Blowfish
	SBlock block(0UL,0UL); //all-zero block
	for(i=0; i<18; )
		Encrypt(block), m_auiP[i++] = block.m_uil, m_auiP[i++] = block.m_uir;
	for(j=0; j<4; j++)
		for(int k=0; k<256; )
			Encrypt(block), m_auiS[j][k++] = block.m_uil, m_auiS[j][k++] = block.m_uir;
	//Initialization Flag
	m_bInit = true;
}

//Resetting the Initialization Vector
void CBlowFish::ResetChain()
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	m_oChain = m_oChain0;
}

//Compute Signature
void CBlowFish::Signature(char* pcSig)
{
	//8+56+1+1+1
	char acSigData[68] = {0};
	strcat(acSigData, "BLOWFISH");
	int iLen = strlen(acSigData);
	memcpy(acSigData+iLen, m_apKey.get(), m_keylength);
	sprintf(acSigData+iLen+m_keylength, "%d%d", m_iMode, m_iPadding);
	CSHA oSHA;
	oSHA.AddData(acSigData, strlen(acSigData));
	oSHA.FinalDigest(pcSig);
}

//Sixteen Round Encipher of Block
void CBlowFish::Encrypt(SBlock& block)
{
	unsigned int uiLeft = block.m_uil;
	unsigned int uiRight = block.m_uir;
	uiLeft ^= m_auiP[0];
	uiRight ^= F(uiLeft)^m_auiP[1]; uiLeft ^= F(uiRight)^m_auiP[2];
	uiRight ^= F(uiLeft)^m_auiP[3]; uiLeft ^= F(uiRight)^m_auiP[4];
	uiRight ^= F(uiLeft)^m_auiP[5]; uiLeft ^= F(uiRight)^m_auiP[6];
	uiRight ^= F(uiLeft)^m_auiP[7]; uiLeft ^= F(uiRight)^m_auiP[8];
	uiRight ^= F(uiLeft)^m_auiP[9]; uiLeft ^= F(uiRight)^m_auiP[10];
	uiRight ^= F(uiLeft)^m_auiP[11]; uiLeft ^= F(uiRight)^m_auiP[12];
	uiRight ^= F(uiLeft)^m_auiP[13]; uiLeft ^= F(uiRight)^m_auiP[14];
	uiRight ^= F(uiLeft)^m_auiP[15]; uiLeft ^= F(uiRight)^m_auiP[16];
	uiRight ^= m_auiP[17];
	block.m_uil = uiRight;
	block.m_uir = uiLeft;
}

//Sixteen Round Decipher of SBlock
void CBlowFish::Decrypt(SBlock& block)
{
	unsigned int uiLeft = block.m_uil;
	unsigned int uiRight = block.m_uir;
	uiLeft ^= m_auiP[17];
	uiRight ^= F(uiLeft)^m_auiP[16]; uiLeft ^= F(uiRight)^m_auiP[15];
	uiRight ^= F(uiLeft)^m_auiP[14]; uiLeft ^= F(uiRight)^m_auiP[13];
	uiRight ^= F(uiLeft)^m_auiP[12]; uiLeft ^= F(uiRight)^m_auiP[11];
	uiRight ^= F(uiLeft)^m_auiP[10]; uiLeft ^= F(uiRight)^m_auiP[9];
	uiRight ^= F(uiLeft)^m_auiP[8]; uiLeft ^= F(uiRight)^m_auiP[7];
	uiRight ^= F(uiLeft)^m_auiP[6]; uiLeft ^= F(uiRight)^m_auiP[5];
	uiRight ^= F(uiLeft)^m_auiP[4]; uiLeft ^= F(uiRight)^m_auiP[3];
	uiRight ^= F(uiLeft)^m_auiP[2]; uiLeft ^= F(uiRight)^m_auiP[1];
	uiRight ^= m_auiP[0];
	block.m_uil = uiRight;
	block.m_uir = uiLeft;
}

//Semi-Portable Byte Shuffling
inline void BytesToBlock(unsigned char const* p, SBlock& b)
{
	unsigned int y;
	//Left
	b.m_uil = 0;
	y = *p++;
	y <<= 24;
	b.m_uil |= y;
	y = *p++;
	y <<= 16;
	b.m_uil |= y;
	y = *p++;
	y <<= 8;
	b.m_uil |= y;
	y = *p++;
	b.m_uil |= y;
	//Right
	b.m_uir = 0;
	y = *p++;
	y <<= 24;
	b.m_uir |= y;
	y = *p++;
	y <<= 16;
	b.m_uir |= y;
	y = *p++;
	y <<= 8;
	b.m_uir |= y;
	y = *p++;
	b.m_uir |= y;
}

inline void BlockToBytes(SBlock const& b, unsigned char* p)
{
	unsigned int y;
	//Right
	y = b.m_uir;
	*--p = Byte(y);
	y = b.m_uir >> 8;
	*--p = Byte(y);
	y = b.m_uir >> 16;
	*--p = Byte(y);
	y = b.m_uir >> 24;
	*--p = Byte(y);
	//Left
	y = b.m_uil;
	*--p = Byte(y);
	y = b.m_uil >> 8;
	*--p = Byte(y);
	y = b.m_uil >> 16;
	*--p = Byte(y);
	y = b.m_uil >> 24;
	*--p = Byte(y);
}

//Encryption for a string of chars
void CBlowFish::Encrypt(char const* in, char* out, size_t n)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	//n should be > 0 and multiple of m_blockSize
	if(n<1 || n%m_blockSize!=0)
		throw runtime_error(string(sm_szErrorMsg6));
	SBlock work;
	if(CBC == m_iMode) //CBC mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			work ^= chain;
			Encrypt(work);
			chain = work;
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
	else if(CFB == m_iMode) //CFB mode, using the Chain
	{
		SBlock chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			Encrypt(chain);
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			work ^= chain;
			chain = work;
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			Encrypt(work);
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
}

//Decryption for a string of chars
void CBlowFish::Decrypt(char const* in, char* out, size_t n)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	//n should be > 0 and multiple of m_blockSize
	if(n<1 || n%m_blockSize!=0)
		throw runtime_error(string(sm_szErrorMsg6));
	SBlock work;
	if(CBC == m_iMode) //CBC mode, using the Chain
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			crypt = work;
			Decrypt(work);
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
	else if(CFB == m_iMode) //CFB mode, using the Chain, not using Decrypt()
	{
		SBlock crypt, chain(m_oChain);
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			Encrypt(chain);
			crypt = work;
			work ^= chain;
			chain = crypt;
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
	else //ECB mode, not using the Chain
	{
		for(; n >= 8; n -= 8, in += 8)
		{
			BytesToBlock(reinterpret_cast<unsigned char const*>(in), work);
			Decrypt(work);
			BlockToBytes(work, reinterpret_cast<unsigned char*>(out+=8));
		}
	}
}

void CBlowFish::EncryptFile(string const& rostrFileIn, string const& rostrFileOut)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	//Check if the same file for input and output
	if(rostrFileIn == rostrFileOut)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg8 << rostrFileIn << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Open Input File
	ifstream in(rostrFileIn.c_str(), ios::binary);
	if(!in)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg7 << rostrFileIn << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Open Output File
	ofstream out(rostrFileOut.c_str(), ios::binary);
	if(!out)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg7 << rostrFileOut << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Computing the signature
	char acSig[33] = {0};
	Signature(acSig);
	//Writing the Signature
	out.write(acSig, 32);
	//Resetting the chain
	ResetChain();
	//Reading from file
	char szLargeBuff[BUFF_LEN+1] = {0};
	char szBuffIn[DATA_LEN+1] = {0};
	char szBuffOut[DATA_LEN+1] = {0};
	CDoubleBuffering oDoubleBuffering(in, szLargeBuff, BUFF_LEN, DATA_LEN);
	int iRead;
	while((iRead=oDoubleBuffering.GetData(szBuffIn)) > 0)
	{
		if(iRead < DATA_LEN)
			iRead = Pad(szBuffIn, iRead);
		//Encrypting
		Encrypt(szBuffIn, szBuffOut, iRead);
		out.write(szBuffOut, iRead);
	}
	in.close();
	out.close();
}

void CBlowFish::DecryptFile(string const& rostrFileIn, string const& rostrFileOut)
{
	if(false==m_bInit)
		throw runtime_error(string(sm_szErrorMsg1));
	//Check if the same file for input and output
	if(rostrFileIn == rostrFileOut)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg8 << rostrFileIn << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Open Input File
	ifstream in(rostrFileIn.c_str(), ios::binary);
	if(!in)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg7 << rostrFileIn << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Open Output File
	ofstream out(rostrFileOut.c_str(), ios::binary);
	if(!out)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg7 << rostrFileOut << "!" << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Computing the signature
	char acSig[33] = {0};
	Signature(acSig);
	char acSig1[33] = {0};
	//Reading the Signature
	in.read(acSig1, 32);
	//Compare the signatures
	if(memcmp(acSig1, acSig, 32) != 0)
	{
		ostrstream ostr;
		ostr << sm_szErrorMsg9 << rostrFileIn << sm_szErrorMsg10 << ends;
		string ostrMsg = ostr.str();
		ostr.freeze(false);
		throw runtime_error(ostrMsg);
	}
	//Resetting the chain
	ResetChain();
	//Reading from file
	char szLargeBuff[BUFF_LEN+1] = {0};
	char szBuffIn[DATA_LEN+1] = {0};
	char szBuffOut[DATA_LEN+1] = {0};
	CDoubleBuffering oDoubleBuffering(in, szLargeBuff, BUFF_LEN, DATA_LEN);
	int iRead;
	while((iRead=oDoubleBuffering.GetData(szBuffIn)) > 0)
	{
		//Encrypting
		Decrypt(szBuffIn, szBuffOut, iRead);
		out.write(szBuffOut, iRead);
	}
	in.close();
	out.close();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -