1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Base64 编解码

Base64 编解码

时间:2022-05-06 05:34:13

相关推荐

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。

Base64编码表 码值 字符 码值 字符 码值 字符 码值 字符0 A 16 Q 32 g 48 w1 B 17 R 33 h 49 x2 C 18 S 34 i 50 y3 D 19 T 35 j 51 z4 E 20 U 36 k 52 05 F 21 V 37 l 53 16 G 22 W 38 m 54 27 H 23 X 39 n 55 38 I 24 Y 40 o 56 49 J 25 Z 41 p 57 510 K 26 a 42 q 58 611 L 27 b 43 r 59 712 M 28 c 44 s 60 813 N 29 d 45 t 61 914 O 30 e 46 u 62 +15 P 31 f 47 v 63 /

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;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。
相关阅读
Base64编码 Base64编解码

Base64编码 Base64编解码

2022-06-26

base64编解码

base64编解码

2021-04-07

Base64编解码原理

Base64编解码原理

2024-02-05

Base64的编解码

Base64的编解码

2021-04-14