C++ 實現Base64編碼

Base64編碼

是網絡上最常見的用於傳輸8Bit字節碼的編碼方式之一,Base64就是一種基於64個可打印字符來表示二進制數據的方法,Base64編碼是從二進制到字符的過程,可用於在HTTP環境下傳遞較長的標識信息。採用Base64編碼具有不可讀性,需要解碼後才能閱讀。

編碼實現過程
想要實現對字符串的base64編碼,首先肯定要知道它的編碼過程,在進行編碼前首先要設置碼錶

const u_char base64tab[64] =
{
 'A','B','C','D' , 'E','F','G','H',
 'I','J','K','L' , 'M','N','O','P',
 'Q','R','S','T' , 'U','V','W','X',
 'Y','Z','a','b' , 'c','d','e','f',
 'g','h','i','j' , 'k','l','m','n',
 'o','p','q','r' , 's','t','u','v',
 'w','x','y','z' , '0','1','2','3',
 '4','5','6','7' , '8','9','+','/'
};

可以看出它的碼錶一共有64個字符,現在就能理解他爲什麼叫base64了,有了編碼的對照碼錶,我們現在就可以深究它的編碼計算過程了,首先假設我們現在有一個明文字符串"ABC"那按照base64的標準,該如何進行編碼呢?首先我們知道在這串字符串中一個字符佔一個字節,一共三個字節,每個字節八位,一共是三組八位共24位二進制數,現在我們需要吧這24位二進制數拆成每組六個字節,一共4組的一串數據就像這樣
在這裏插入圖片描述這樣一來就把明文的二進制碼拆開了,拆開後是六位二進制數,要放入內存必須要一個字節才行,那就再每個六位二進制數前面加兩個0剛好湊夠一個字節

現在還有一共問題,那就是三個字節的字符串剛好可以拆成四組,那不是三個字節的字符串,或字符個數不是三的倍數的字符串怎麼編碼呢?當然也有辦法,如果有一個字符串一共長12個字節,那我們分成四組三個字節的短字符串,按組來處理就好了。那假如是一個13個字節的字符串呢,13不是3的倍數,那又該怎麼分組呢,首先3的倍數基本上是每隔兩個數就會出現一次,那就先按12來算,可以分成四組,最後一組不足三個字節,那就補兩個“==”字符串,同樣的假如剩餘兩個字符串那就補一個·“=”
如圖所示
在這裏插入圖片描述假設是字符串“ABCE"編碼過程大致就是這樣,同樣也是分爲每組6個後方便存入內存,在高位補兩位0。

在這裏我們新轉換到的數字並不是base64密文的ascii碼,這裏獲取到的數字是一個索引下標,沒錯就是我們剛剛設置的那個有64個字符的base64編碼表的下標,我們根據算出的小標就能找到密文對應的字符,再將這些字符存入字符串就得到了一串base64編碼的字符串,要注意的是最後一組如果不夠三個字節,補上去的兩個或一個“=”不參與編碼位運算

代碼實現
首先在C++中最小的存儲單位是字節,所以我們無法直接將每一位拆開重組,那如何將字節中的每一位拆分重組呢?沒錯就是位移運算

string Base64::Base64Encode
(
	_In_ string tsrc,
	_In_ u_long srcsize 
)
{
	const u_char* src = (const u_char*)tsrc.c_str();
	u_char* tempBuff = new u_char[3];
	string destStr;
	//取到最後剩幾個數據
	int lastNumb = srcsize % 3;

	//分爲三組處理
	int i;
	for (i = 0; i < (srcsize / 3); i++)
	{
		memset(tempBuff, 0x00, 3);
		memcpy(tempBuff, (src+i*3), 3);

		destStr += base64tab[(tempBuff[0] >> 2)];
		destStr += base64tab[(((tempBuff[0] & 0x03) << 4) | (tempBuff[1] >> 4))];
		destStr += base64tab[(((tempBuff[1] & 0x0f) << 2) | (tempBuff[2] >> 6))];
		destStr += base64tab[(tempBuff[2] & 0x3f)];
	}
	//剩餘不夠一組的數據處理
	if (lastNumb == 1)
	{
		memset(tempBuff, 0x00, 3);
		memcpy(tempBuff, (src + i * 3), 1);
		destStr += base64tab[(tempBuff[0] >> 2)];
		destStr += base64tab[(tempBuff[0] & 0x03) << 4];
		destStr.append("==");
	}
	if (lastNumb == 2)
	{
		memset(tempBuff, 0x00, 2);
		memcpy(tempBuff, (src + i * 3), 2);
		destStr += base64tab[(tempBuff[0] >> 2)];
		destStr += base64tab[(((tempBuff[0] & 0x03) << 4) | (tempBuff[1] >> 4))];
		destStr += base64tab[((tempBuff[1] & 0x0f) << 2)];
		destStr.append("=");
	}
//釋放內存
	delete[] tempBuff;
	return destStr;
}

z我這裏實現了一個base64編解碼的類,在類中實現了一個靜態函數,完整項目代碼已上傳github,地址在最後
對於解碼,就是對編碼的逆運算,沒有什麼好說的,
可以參考這篇文章,個人感覺解碼效率還挺高
Base64編解碼及其C++實現 原創
這種方法感覺效率很高,可以參考

完整項目地址github:
CppFastSolution

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章