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

📄 algorithm.cpp

📁 LINUX下发送邮件的库,测试很好用,有各种发送测试的例子
💻 CPP
字号:
/************************************************************************* *                                                                       * * This program is free software; you can redistribute it and/or modify  * * it under the terms of the GNU General Public License as published by  * * the Free Software Foundation; either version 2 of the License, or     * * (at your option) any later version.                                   * *                                                                       * *************************************************************************/#include "algorithm.h"/** * Encode str with the given codec. * * @param str   The string that should be encoded. * @param codec The codec that should be used. * @returns The encoded string. */string Algorithm::encode (const string &str, CODEC codec){	string enc_str = "";	switch (codec)	{		case BASE64:			Algorithm::enc_base64 (str, &enc_str);			break;		case BASE64_NIL:			Algorithm::enc_base64_nil (str, &enc_str);			break;	}		return (enc_str);}/** * Decode str with the given codec. * * @param str   The string that should be decoded. * @param codec The codec that should be used. * @returns The encoded string. * * @throws DecodeException *                     If the BASE64 data was invalid. */string Algorithm::decode (const string &str, CODEC codec){	string dec_str = "";	int ret = 0;	switch (codec)	{		case BASE64:			ret = Algorithm::dec_base64 (str, &dec_str);			if (ret == -1)			{				string msg = LIBSMTP_I18N_1 ("Invalid Base64 Data.");				throw (DecodeException (msg, "Algorithm::decode()", 1));			}			break;		case BASE64_NIL:			ret = Algorithm::dec_base64_nil (str, &dec_str);			if (ret == -1)			{				string msg = LIBSMTP_I18N_1 ("Invalid Base64 Data.");				throw (DecodeException (msg, "Algorithm::decode()", 2));			}			break;	}		return (dec_str);}/** * Calculates the keyed md5sum. (rfc2104) * * @param text   The text that should be checksummed. * @param key    The key that should be used. * @param digest The checksum that is calculated out of key  *               and text will be stored at digest. digest *               needs to be at least 16 Bytes big. */void Algorithm::hmac_md5 (const string &str, const string &key, unsigned char * digest){	unsigned int md_len;	digest = HMAC	( 		EVP_md5 (), 		(unsigned char*)key.c_str (), key.length (), 		(unsigned char*)str.c_str (), str.length (), 		digest, &md_len	);}/** * Calculates the keyed sha1sum. (rfc2104) * * @param text   The text that should be checksummed. * @param key    The key that should be used. * @param digest The checksum that is calculated out of key  *               and text will be stored at digest. digest *               needs to be at least 20 Bytes big. */void Algorithm::hmac_sha1 (const string &str, const string &key, unsigned char * digest){	unsigned int md_len;	digest = HMAC	( 		EVP_sha1 (), 		(unsigned char*)key.c_str (), key.length (), 		(unsigned char*)str.c_str (), str.length (), 		digest, &md_len	);}/** * Calculates the keyed sha1sum and returns the digest as a  * string. (rfc2104) * Just for your convenience. * * @param str    The text that should be checksummed. * @param key    The key that should be used. * @returns      A string representation of the checksum  *               that was calculated using str and key. */string Algorithm::hmac_sha1_str (const string &str, const string &key){	unsigned char digest[20];	Algorithm::hmac_sha1 (str, key, (unsigned char*)digest);	char str_digest[41];	unsigned int i;	for (i = 0; i < 20; i++)	{		sprintf (str_digest+(i*2),"%02x", digest[i]);	}	str_digest[40] = '\0';	return (str_digest);}/** * Calculates the keyed md5sum and returns the digest as a  * string. (rfc2104) * Just for your convenience. * * @param str    The text that should be checksummed. * @param key    The key that should be used. * @returns      A string representation of the checksum  *               that was calculated using str and key. */string Algorithm::hmac_md5_str (const string &str, const string &key){	unsigned char digest[16];	Algorithm::hmac_md5 (str, key, (unsigned char *)digest);	char str_digest[33];	unsigned int i;	for (i = 0; i < 16; i++)	{		sprintf (str_digest+(i*2),"%02x", digest[i]);	}	str_digest[32] = '\0';	return (str_digest);}/** * Encode orig_str with the base64 codec and store * the result in the string pointed by enc_str. * * @param orig_str The string that should be encoded. * @param enc_str  The resulting encoded string will be stored *                 at the address pointed to by enc_str. */void Algorithm::enc_base64 (const string &orig_str, string * enc_str){	unsigned int remain  = orig_str.length () % 3;	unsigned int idx = 0;	while (idx < (orig_str.length ()-remain))	{		int concat = ((unsigned char)orig_str[idx+0] << 16) | 		((unsigned char)orig_str[idx+1] <<  8) | 		((unsigned char)orig_str[idx+2] <<  0);		(*enc_str) += tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += tbl_base64[(concat >>  6) & 0x3F];		(*enc_str) += tbl_base64[(concat >>  0) & 0x3F];		idx += 3;	}	if (remain == 2)	{		int concat = (orig_str[idx+0] << 16) | 		(orig_str[idx+1] <<  8);		(*enc_str) += Algorithm::tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >>  6) & 0x3F];		(*enc_str) += '=';	}	else if (remain == 1)	{		int concat = (orig_str[idx+0] << 16);		(*enc_str) += Algorithm::tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += '=';		(*enc_str) += '=';	}}/** * Decode enc_str with the base64 codec and store * the result in the string pointed by orig_str. * If successfull 0 is returned, and -1 if the * base64 data was invalid. * * @param enc_str  The string that should be decoded. * @param orig_str The resulting decoded string will be stored *                 at the address pointed to by orig_str. * @returns 0 if the decoding process was successfull and -1 if * the base64 data was invalid. */int Algorithm::dec_base64 (const string &enc_str, string * orig_str){	if (enc_str.length () % 4)	{		return (-1);	}	unsigned int idx = 0;	while (idx < enc_str.length ())	{		char b[] = { -1, -1, -1 , -1 };				for (int i = 0; i < 4; i++)		{			for (int z = 0; z < 64; z++)			{				if (Algorithm::tbl_base64[z] == enc_str[idx+i])				{					b[i] = z;					break;				}				else if (enc_str[idx+i] == '=')				{					if (enc_str.length () == (idx+i+2))					{						b[2] = 0x7F;						b[3] = 0x7F;						break;					}					if (enc_str.length () == (idx+i+1))					{						b[3] = 0x7F;						break;					}					else					{						return (-1);					}				}			}			if (b[i] == -1)			{				return (-1);			}		}		int concat = (b[0] << 18) | 					 (b[1] << 12) | 					 (b[2] <<  6) |					 (b[3] <<  0);		if (b[2] == 0x7F)		{			(*orig_str) += (char)((concat >> 16) & 0xFF); 		}		else if (b[3] == 0x7F)		{			(*orig_str) += (char)((concat >> 16) & 0xFF); 			(*orig_str) += (char)((concat >> 8) & 0xFF); 		}		else		{			(*orig_str) += (char)((concat >> 16) & 0xFF); 			(*orig_str) += (char)((concat >> 8) & 0xFF); 			(*orig_str) += (char)((concat >> 0) & 0xFF); 		}		idx += 4;	}	return (0);}/** * Encode enc_str with a slightly advanced base64 codec  * and store the result in the string pointed by orig_str. * The sequence "<NIL>" will be substituted with one zero byte. * * @param orig_str The string that should be encoded. * @param enc_str  The resulting encoded string will be stored *                 at the address pointed to by enc_str. */void Algorithm::enc_base64_nil (string orig_str, string * enc_str){	vector<unsigned int> nil_chars;	unsigned int pos;	while ((pos = orig_str.find ("<NIL>")) != string::npos)	{		orig_str.replace (pos, 5, ".");		nil_chars.push_back (pos);	}	int remain = orig_str.length () % 3;	unsigned int idx = 0;	while (idx < (orig_str.length ()-remain))	{		int concat = 0;		if (find (nil_chars.begin (), nil_chars.end (), idx) != nil_chars.end ())		{    			concat = 0 << 16;		}		else		{			concat = ((unsigned char)orig_str[idx+0] << 16);		}		if (find (nil_chars.begin (), nil_chars.end (), idx+1) != nil_chars.end ())		{    			concat |= 0 << 8;		}		else		{			concat |= ((unsigned char)orig_str[idx+1] << 8);		}		if (find (nil_chars.begin (), nil_chars.end (), idx+2) != nil_chars.end ())		{    			concat |= 0 << 0;		}		else		{			concat |= ((unsigned char)orig_str[idx+2] << 0);		}		(*enc_str) += Algorithm::tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >>  6) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >>  0) & 0x3F];		idx += 3;	}	if (remain == 2)	{		int concat = 0;		if (find (nil_chars.begin (), nil_chars.end (), idx) != nil_chars.end ())		{    			concat = 0 << 16;		}		else		{			concat = ((unsigned char)orig_str[idx+0] << 16);		}		if (find (nil_chars.begin (), nil_chars.end (), idx+1) != nil_chars.end ())		{    			concat |= 0 << 8;		}		else		{			concat |= ((unsigned char)orig_str[idx+1] << 8);		}		(*enc_str) += Algorithm::tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >>  6) & 0x3F];		(*enc_str) += '=';	}	else if (remain == 1)	{		int concat = 0;		if (find (nil_chars.begin (), nil_chars.end (), idx) != nil_chars.end ())		{    			concat = 0 << 16;		}		else		{			concat = ((unsigned char)orig_str[idx+0] << 16);		}		(*enc_str) += Algorithm::tbl_base64[(concat >> 18) & 0x3F];		(*enc_str) += Algorithm::tbl_base64[(concat >> 12) & 0x3F];		(*enc_str) += '=';		(*enc_str) += '=';	}}/** * Decode enc_str with a slightly advanced base64  * codec and store the result in the string pointed  * by orig_str. * Each zero byte will be substituted with the * sequence "<NIL>". * If successfull 0 is returned, and -1 if the * base64 data was invalid. * * @param enc_str  The string that should be decoded. * @param orig_str The resulting decoded string will be stored *                 at the address pointed to by orig_str. * @returns 0 if the decodeing process was successfull and -1 if * the base64 data was invalid. */int Algorithm::dec_base64_nil (const string &enc_str, string * orig_str){	if (enc_str.length () % 4)	{		return (-1);	}	unsigned int idx = 0;	while (idx < enc_str.length ())	{		char b[] = { -1, -1, -1 , -1 };				for (int i = 0; i < 4; i++)		{			for (int z = 0; z < 64; z++)			{				if (Algorithm::tbl_base64[z] == enc_str[idx+i])				{					b[i] = z;					break;				}				else if (enc_str[idx+i] == '=')				{					if (enc_str.length () == (idx+i+2))					{						b[2] = 0x7F;						b[3] = 0x7F;						break;					}					if (enc_str.length () == (idx+i+1))					{						b[3] = 0x7F;						break;					}					else					{						return (-1);					}				}			}			if (b[i] == -1)			{				return (-1);			}		}		int concat = (b[0] << 18) | 					 (b[1] << 12) |					 (b[2] <<  6) |					 (b[3] <<  0);		if (b[2] == 0x7F)		{			char c = (char)((concat >> 16) & 0xFF); 			if (c == '\0')			{				(*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}		}		else if (b[3] == 0x7F)		{			char c = (char)((concat >> 16) & 0xFF); 			if (c == '\0')			{				(*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}			c = (char)((concat >> 8) & 0xFF); 			if (c == '\0')			{			  (*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}		}		else		{			char c = (char)((concat >> 16) & 0xFF); 			if (c == '\0')			{				(*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}			c = (char)((concat >> 8) & 0xFF); 			if (c == '\0')			{				(*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}			c = (char)((concat >> 0) & 0xFF); 			if (c == '\0')			{				(*orig_str) += "<NIL>";			}			else			{				(*orig_str) += c;			}		}		idx += 4;	}	return (0);}/** * the base64 character table */char Algorithm::tbl_base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 

⌨️ 快捷键说明

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