This is the 21st day of my participation in the August Text Challenge.More challenges in August

In a project, after the leopard print is compressed and encrypted, the last step is usually Base64 encoding. Because base64 encoded string is more suitable for different platforms, different languages transmission.

Advantages of Base64 encoding:

  • The algorithm encodes, not compresses, and only increases the number of bytes after encoding (usually 1/3 more than before, e.g., 3 before, 4 after encoding).
  • The algorithm is simple and does not affect the efficiency
  • The algorithm is reversible, the decoding is very convenient, not used for private transmission.
  • After all, encoded, the naked eye can’t read the original content.
  • The encrypted string only [0-9a-zA-z +/=] unprintable characters (translation characters) can also be transmitted

Why code

Any data in a computer is stored in ASCII, which is invisible characters between 128 and 255. Data exchange on the network, from A to B, often through A number of routers, different devices on the character processing methods are somewhat different, invisible characters may be incorrectly processed, is not conducive to transmission, so first do A Base64 encoding, into visible characters, so the possibility of error is relatively large.

Look at the English version:

When you have some binary data that you want to ship across a network, you generally don’t do it by just streaming the bits and bytes over the wire in a raw format. Why? because some media are made for streaming text. You never know — some protocols may interpret your binary data as control characters (like a modem), or your binary data could be screwed up because the underlying protocol might think that you’ve entered a special character combination (like how FTP translates line endings). So to get around this, people encode the binary data into characters. Base64 is one of these types of encodings. Why 64? Because you can generally rely on the same 64 characters being present in many character sets, and you can be reasonably confident that your data’s going to end up on the other side of the wire uncorrupted.

Usage scenarios

  • For certificates, especially root certificates, they are base64 encoded and downloaded by many people on the web
  • E-mail attachments are typically base64 encoded because attachments tend to have invisible characters
  • For example, the value of the key and value fields in HTTP must be URLEncode, because special symbols and meanings are written, so these characters need to be transmitted and parsed back.
  • If you embed XML directly, as in another XML file, the XML tags will be messy and difficult to parse, so you need to compile the XML into a string of byte arrays, and compile it into visible characters.
  • Small images in web pages can be embedded directly in Base64 encoding without consuming network resources with link requests.
  • The older plain-text protocol SMTP, which occasionally transfers a file, requires base64

Base64 encoding steps

  • Converts the string to be encoded to a binary representation
  • Three bytes in a group, that’s 24 bits in a group
  • Divide the 24 bits into 4 groups of 6 bits, and each group signature complement 00 converts 6 bits into 8 bits, from 3 bytes to 4 bytes
  • Compute the decimal representation of these four bytes, and concatenate the string to form the final Base64 encoding, corresponding to the ASCII table.

Base64 source

base64.h

#include "Base64.h"
 
const std: :string CBase64::base64_chars =   
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
	"abcdefghijklmnopqrstuvwxyz"  
	"0123456789 + /";  
 
 
int CBase64::find_utf_8_bit_head(const unsigned char *src_content,int src_size )
{
	int i_ret = - 1;
	int byteNum = 0;		/ / the number of characters
	if( src_content )
	{ 
		for(int i = src_size- 1; i >= 0; i--)
		{
			if( 0 == (src_content[i] >> 7 ) )
			{
				byteNum = 1;
				i_ret = src_size - i;
				break;
			}
			if( 0x06 == (src_content[i]>> 5) )
			{
				byteNum = 2;
				i_ret = src_size - i;
				break;
			}
			if( 0x0E == (src_content[i] >> 4) )
			{
				byteNum = 3;
				i_ret = src_size - i;
				break;
			}
			if( 0x1E == (src_content[i] >> 3) )
			{
				byteNum = 4;
				i_ret = src_size - i;
				break;
			}
			if( 0x3E == (src_content[i] >> 2) )
			{
				byteNum = 5;
				i_ret = src_size - i;
				break;
			}
			if( 0x7E == (src_content[i] >> 1) ) 
			{
				byteNum = 6;
				i_ret = src_size - i;
				break; }}if( i_ret == byteNum ) i_ret = - 1;
	}
	return i_ret;
}
 
 
std: :string CBase64::base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
	std: :string ret;  
	int i = 0;  
	int j = 0;  
	unsigned char char_array_3[3];  
	unsigned char char_array_4[4];  
 
	while (in_len--) {  
		char_array_3[i++] = *(bytes_to_encode++);  
		if (i == 3) {  
			char_array_4[0] = (char_array_3[0] & 0xfc) > >2;  
			char_array_4[1] = ((char_array_3[0] & 0x03) < <4) + ((char_array_3[1] & 0xf0) > >4);  
			char_array_4[2] = ((char_array_3[1] & 0x0f) < <2) + ((char_array_3[2] & 0xc0) > >6);  
			char_array_4[3] = char_array_3[2] & 0x3f;  
 
			for(i = 0; (i <4); i++) ret += base64_chars[char_array_4[i]]; i =0; }}if (i)  
	{  
		for(j = i; j < 3; j++)  
			char_array_3[j] = '\ 0';  
 
		char_array_4[0] = (char_array_3[0] & 0xfc) > >2;  
		char_array_4[1] = ((char_array_3[0] & 0x03) < <4) + ((char_array_3[1] & 0xf0) > >4);  
		char_array_4[2] = ((char_array_3[1] & 0x0f) < <2) + ((char_array_3[2] & 0xc0) > >6);  
		char_array_4[3] = char_array_3[2] & 0x3f;  
 
		for (j = 0; (j < i + 1); j++)  
			ret += base64_chars[char_array_4[j]];  
 
		while((i++ < 3))  
			ret += '=';  
 
	}  
 
	return ret;  
 
}
 
 
//CString CBase64::Base64Encode(LPCTSTR lpszSrc)
/ / {
//	char* strSrc = new char[_tcslen(lpszSrc)+1];
//	ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
//	strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
//	std::string str = base64_encode((unsigned char*)strSrc, (int)strlen(strSrc));
//	CString strDst = str.c_str();
//	return strDst;
/ /}
 
std: :string CBase64::Base64Encode(char* lpszSrc)
{
	int str_len = strlen(lpszSrc);
	int find_index = find_utf_8_bit_head((unsigned char*)lpszSrc, str_len);
	if(find_index > - 1)
	{
		memset(lpszSrc+(str_len-find_index), 0, find_index);
	}
	str_len = strlen(lpszSrc);
	return base64_encode((unsigned char*)lpszSrc, str_len);
}
 
std: :string CBase64::base64_decode(const unsigned char* bytes_to_encode, unsigned int in_len) {  
	int i = 0;  
	int j = 0;  
	int in_ = 0;  
	unsigned char char_array_4[4], char_array_3[3];  
	std: :string ret;  
 
	while(in_len-- && ( bytes_to_encode[in_] ! ='=') /*&& is_base64(bytes_to_encode[in_])*/) {  
		char_array_4[i++] = bytes_to_encode[in_]; in_++;  
		if (i ==4) {  
			for (i = 0; i <4; i++)  
				char_array_4[i] = base64_chars.find(char_array_4[i]);  
 
			char_array_3[0] = (char_array_4[0] < <2) + ((char_array_4[1] & 0x30) > >4);  
			char_array_3[1] = ((char_array_4[1] & 0xf) < <4) + ((char_array_4[2] & 0x3c) > >2);  
			char_array_3[2] = ((char_array_4[2] & 0x3) < <6) + char_array_4[3];  
 
			for (i = 0; (i < 3); i++)  
				ret += char_array_3[i];  
			i = 0; }}if (i) {  
		for (j = i; j <4; j++)  
			char_array_4[j] = 0;  
 
		for (j = 0; j <4; j++)  
			char_array_4[j] = base64_chars.find(char_array_4[j]);  
 
		char_array_3[0] = (char_array_4[0] < <2) + ((char_array_4[1] & 0x30) > >4);  
		char_array_3[1] = ((char_array_4[1] & 0xf) < <4) + ((char_array_4[2] & 0x3c) > >2);  
		char_array_3[2] = ((char_array_4[2] & 0x3) < <6) + char_array_4[3];  
 
		for (j = 0; (j < i - 1); j++) ret += char_array_3[j];  
	}  
 
	return ret;  
}    
 
//CString CBase64::Base64Decode(LPCTSTR lpszSrc)
/ / {
//	char* strSrc = new char[_tcslen(lpszSrc)+1];
//	ZeroMemory(strSrc, _tcslen(lpszSrc)+1);
//	strcpy(strSrc, (char*)(_bstr_t(lpszSrc)));
//	std::string str = base64_decode((unsigned char*)strSrc, (int)strlen(strSrc));
//	CString strDst = str.c_str();
//	return strDst;
/ /}
 
std: :string CBase64::Base64Decode(char* lpszSrc)
{
	return base64_decode((unsigned char*)lpszSrc, (int)strlen(lpszSrc));
}
Copy the code

base64.cpp

#include "Base64.h" const std::string CBase64::base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789 + /"; int CBase64::find_utf_8_bit_head(const unsigned char *src_content,int src_size ) { int i_ret = -1; int byteNum = 0; If (src_content) {for(int I = src_size-1; i >= 0; i--) { if( 0 == (src_content[i] >> 7 ) ) { byteNum = 1; i_ret = src_size - i; break; } if( 0x06 == (src_content[i]>> 5) ) { byteNum = 2; i_ret = src_size - i; break; } if( 0x0E == (src_content[i] >> 4) ) { byteNum = 3; i_ret = src_size - i; break; } if( 0x1E == (src_content[i] >> 3) ) { byteNum = 4; i_ret = src_size - i; break; } if( 0x3E == (src_content[i] >> 2) ) { byteNum = 5; i_ret = src_size - i; break; } if( 0x7E == (src_content[i] >> 1) ) { byteNum = 6; i_ret = src_size - i; break; } } if( i_ret == byteNum ) i_ret = -1; } return i_ret; } std::string CBase64::base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } //CString CBase64::Base64Encode(LPCTSTR lpszSrc) //{ // char* strSrc = new char[_tcslen(lpszSrc)+1]; // ZeroMemory(strSrc, _tcslen(lpszSrc)+1); // strcpy(strSrc, (char*)(_bstr_t(lpszSrc))); // std::string str = base64_encode((unsigned char*)strSrc, (int)strlen(strSrc)); // CString strDst = str.c_str(); // return strDst; //} std::string CBase64::Base64Encode(char* lpszSrc) { int str_len = strlen(lpszSrc); int find_index = find_utf_8_bit_head((unsigned char*)lpszSrc, str_len); if(find_index > -1) { memset(lpszSrc+(str_len-find_index), 0, find_index); } str_len = strlen(lpszSrc); return base64_encode((unsigned char*)lpszSrc, str_len); } std::string CBase64::base64_decode(const unsigned char* bytes_to_encode, unsigned int in_len) { int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; while (in_len-- && ( bytes_to_encode[in_] ! = '=') /*&& is_base64(bytes_to_encode[in_])*/) { char_array_4[i++] = bytes_to_encode[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = base64_chars.find(char_array_4[i]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = base64_chars.find(char_array_4[j]); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; } //CString CBase64::Base64Decode(LPCTSTR lpszSrc) //{ // char* strSrc = new char[_tcslen(lpszSrc)+1]; // ZeroMemory(strSrc, _tcslen(lpszSrc)+1); // strcpy(strSrc, (char*)(_bstr_t(lpszSrc))); // std::string str = base64_decode((unsigned char*)strSrc, (int)strlen(strSrc)); // CString strDst = str.c_str(); // return strDst; //} std::string CBase64::Base64Decode(char* lpszSrc) { return base64_decode((unsigned char*)lpszSrc, (int)strlen(lpszSrc)); }Copy the code