Base64 编解码
生活随笔
收集整理的這篇文章主要介紹了
Base64 编解码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Base64編碼簡介
Base64用來將binary的字節序列數據編碼成ASCII字符序列構成的文本。其使用的字符包括大小寫字母各26個,加上10個數字,和加號“+”,斜杠“/”,一共64個字符。另外還使用等號“=”用來作為后綴。
Base64編碼要求把3個8位字節(3*8=24)轉化為4個6位的字節(4*6=24),之后在6位的前面補兩個0,形成8位一個字節的形式。如果剩下的字符不足3個字節,則用0填充,最后的輸出字符時使用'='作為結尾,因此編碼后輸出的文本末尾可能會出現1或2個'='。
為了保證所輸出的編碼字符都是可讀的,Base64制定了一個編碼表,以便進行統一轉換。編碼表的大小為2^6=64。
?
C++實現
#ifndef __BASE64_UTILS__ #define __BASE64_UTILS__#include <string>using std::string;class Base64Utils { public:Base64Utils(void);~Base64Utils(void);/** 將一個字節數組中的數據轉為一個 base64 格式的數組*/static string Encode(const unsigned char* pEncodeData, int nLength);/** nLength 為 0 時返回需要 pOutBuffer 需要分配的大小; 否則解碼數據, 并存入 pOutBuffer 指向的內存中. 返回值: 失敗時返回0. 否則返回反解碼后的字符的個數*/static int Decode(const string& strBase64, unsigned char* pOutBuffer, int nLength);/** 解析為一個字符串(由調用者確定解出的字符中不包含'\0'才能能調用此函數,否則返回的結果可能不是期望的值) */static string DecodeToString(const string& strBase64);/** 檢查一個字符是否是 base64 編碼的字符 */static bool CheckBase64(unsigned char bas64Char);protected:template <class T> static T min(T left, T right); };#endif __BASE64_UTILS__?
#include "Base64Utils.h"// Base64 編碼所用的字符, 其順序由 base64 協議規定 static const string BASE64_ENCODE_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";// 將 ascii 碼表中, 對應的 Base64 字符的改成 Base64 字符表中的索引值, 以便解碼時進行轉行轉換 static const unsigned char BASE64_DECODE_TABLE[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62, // '+'0, 0, 0,63, // '/'52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'0, 0, 0, 0, 0, 0, 0,0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'0, 0, 0, 0, 0, 0,26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z' };static const unsigned char BASE64_END_CHARACTER = '=';Base64Utils::Base64Utils(void) { }Base64Utils::~Base64Utils(void) { }template <class T> T Base64Utils::min(T left, T right) {return (left < right) ? left : right; }bool Base64Utils::CheckBase64(unsigned char bas64Char) {return (BASE64_ENCODE_TABLE.find(bas64Char) != -1) ? true : false; }string Base64Utils::Encode(const unsigned char* pEncodeData, int nLength) {string strBase64;int i = 0;for (; i + 2 < nLength; i += 3){strBase64.push_back(BASE64_ENCODE_TABLE.at((pEncodeData[i] >> 2) & 0x3f));strBase64.push_back(BASE64_ENCODE_TABLE.at(((pEncodeData[i] & 0x03) << 4) | ((pEncodeData[i + 1] >> 4) & 0x0f)));strBase64.push_back(BASE64_ENCODE_TABLE.at(((pEncodeData[i + 1] & 0x0f) << 2) | ((pEncodeData[i + 2] >> 6) & 0x03)));strBase64.push_back(BASE64_ENCODE_TABLE.at(pEncodeData[i + 2] & 0x3f));}if (i < nLength){strBase64.push_back(BASE64_ENCODE_TABLE.at((pEncodeData[i] >> 2) & 0x3f));if (i + 1 < nLength){strBase64.push_back(BASE64_ENCODE_TABLE.at(((pEncodeData[i] & 0x03) << 4) | ((pEncodeData[i + 1] >> 4) & 0x0f)));strBase64.push_back(BASE64_ENCODE_TABLE.at(((pEncodeData[i + 1] & 0x0f) << 2)));}else{strBase64.push_back(BASE64_ENCODE_TABLE.at(((pEncodeData[i] & 0x03) << 4)));strBase64.push_back(BASE64_END_CHARACTER);}strBase64.push_back(BASE64_END_CHARACTER);}return strBase64; }int Base64Utils::Decode(const string& strBase64, unsigned char* pOutBuffer, int nLength) {nLength = abs(nLength);int nBase64 = strBase64.length();/** 不符合 base64 字符串長度要求的字符串, 不是 base64 編碼格式的字符串, 返回 0 */if ((nBase64 == 0) || ((nBase64 % 4) != 0)) {return 0;}int nNeedSize = nBase64 * 3 / 4;if (strBase64.at(nBase64 - 1) == BASE64_END_CHARACTER)nNeedSize--;if (strBase64.at(nBase64 - 2) == BASE64_END_CHARACTER)nNeedSize--;if (0 == nLength){return nNeedSize;}nNeedSize = min(nNeedSize, nLength);const int nSizeOfDecode = sizeof(BASE64_DECODE_TABLE);int index = 0;int k = 0;unsigned char byteValue;unsigned char base64Char;unsigned char base64Arr[4] = {0};for (int i = 0; i < nBase64; i++){base64Char = strBase64.at(i);if (base64Char == BASE64_END_CHARACTER) // 遇到結速符 {break;}/**如果 base64字符為編碼表中只有一個字符, 其解碼后值一定為 0否則, 到解碼表中查找對應的值, 如果找到, 并且值不為 0, 才是符合的 base64 編碼的字符.如果不是 base64 編碼表中的字符, 則解碼失敗, 設置返回值為 0*/if (base64Char == BASE64_ENCODE_TABLE.at(0)){byteValue = 0;}else{if (base64Char < nSizeOfDecode){byteValue = BASE64_DECODE_TABLE[base64Char];}if (byteValue == 0){nNeedSize = 0;break;}}base64Arr[k++] = byteValue;if (k == 4){if (index >= nNeedSize)break;pOutBuffer[index++] = ((base64Arr[0] & 0x3f) << 2) | ((base64Arr[1] & 0x30) >> 4);if (index >= nNeedSize)break;pOutBuffer[index++] = ((base64Arr[1] & 0x0f) << 4) | ((base64Arr[2] & 0x3c) >> 2);if (index >= nNeedSize)break;pOutBuffer[index++] = ((base64Arr[2] & 0x03) << 6) | ((base64Arr[3] & 0x3f));k = 0;}}if ((k != 0) && (index < nNeedSize)){for (; k < 4; k++){base64Arr[k] = 0;}if (index < nNeedSize)pOutBuffer[index++] = ((base64Arr[0] & 0x3f) << 2) | ((base64Arr[1] & 0x30) >> 4);if (index < nNeedSize)pOutBuffer[index++] = ((base64Arr[1] & 0x0f) << 4) | ((base64Arr[2] & 0x3c) >> 2);if (index < nNeedSize)pOutBuffer[index++] = ((base64Arr[2] & 0x03) << 6) | ((base64Arr[3] & 0x3f));}return nNeedSize; }string Base64Utils::DecodeToString(const string& strBase64) {string strResult;int nSize = Decode(strBase64, NULL, 0);if (nSize == 0){return strResult;}unsigned char* pOutBuffer = new unsigned char[nSize + 1];if (!pOutBuffer){return strResult;}pOutBuffer[nSize] = 0;nSize = Decode(strBase64, pOutBuffer, nSize);if (nSize != 0){strResult = reinterpret_cast<char*>(pOutBuffer);}delete[] pOutBuffer;pOutBuffer = NULL;return strResult; }?
測試代碼
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <iostream> #include "Base64Utils.h"#define PRINT_BYTE(str, len) {printf("[%03d]", len); for(int t = 0; t < len; t++) printf("%c", str[t]); printf("\n");}int _tmain(int argc, _TCHAR* argv[]) {unsigned char pBuffer[] = "~!@#$%^&\0*(\t)_+{}:\"?></.,;'[]\\";int nCount = sizeof(pBuffer);printf("count=%d\n", nCount);for (int i = 1; i <= nCount; i++){string str(&pBuffer[0], &pBuffer[i]);printf("---------- input %d ------------\n", i);printf("%s\n", str.c_str());string strBase64My = Base64Utils::Encode(pBuffer, i);printf("%s\n", strBase64My.c_str());int nOutSize = Base64Utils::Decode(strBase64My, NULL, 0);printf("need buffer : %d\n", nOutSize);//printf("decode:%s\n", Base64Utils::DecodeToString(strBase64My).c_str());//if (strBase64My.length() > 2)//{// strBase64My.replace(strBase64My.begin() + 2, strBase64My.begin() + 3, 1, ',');// printf("%s\n", strBase64My.c_str());//}int j = nOutSize;for (; j > 0; j--){unsigned char* pOutBuffer = new unsigned char[j + 1];memset(pOutBuffer, 0, j + 1);//pOutBuffer[j] = 0;j = Base64Utils::Decode(strBase64My, pOutBuffer, j);// printf("[%03d]%s\n", j, pOutBuffer); PRINT_BYTE(pOutBuffer, j);delete[] pOutBuffer;pOutBuffer = NULL;}}system("pause");return 0; }?
轉載于:https://www.cnblogs.com/diysoul/p/5816240.html
總結
以上是生活随笔為你收集整理的Base64 编解码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于DOM
- 下一篇: wpf 将Style应用到 ListVi