您的位置:首页 > 编程语言 > C语言/C++

一个C++版本的base64编码/解码

2014-05-27 17:44 211 查看
编码转换表:

{
'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','+','/','='
}


base64编码规则:

每次从待编码字符串中取3个字符(24个位),

每6个位为一组, 并在前面补上"00"组成一个新的字符(在转换表中找到对应ascii码的字符)

当待编码字符串长度不为3的倍数时, 每差一个字节, 则补上一个"="号;

例如"abcd" (97, 98, 99, 100)

将其ascii码转成二进制为"01100001011000100110001101100100"

每次取3个字符为"abc", "d"

"abc"的ascii码连起来为"011000010110001001100011",

每6位为一组并在其前面补上"00", 则是“00011000”(24), "00010110"(22), "00001001"(9),
"00100011"(35);

在表中找到对应的字符“YWJj”

再次取3个字符, 这里只剩下d了。。

“d”的ascii码为"01100100";

同样6位一组并在其前面补上"00", 则是 "00011001"(25), "00000000"(0) //后面没得取了, 所以只有2个字符

在表中找到对应字符为“ZA”;

由于差2, "abcd"的长度才为3的倍数, 所以补上2个"=";

最终转换结果为:"YWJjZA=="

base64解码规则:

跟编码规则相反, 这里就不写了;

代码:

#ifndef __BASE64__
#define __BASE64__

#include <string>

using std::string;

class Base64
{
public:
static string encode(string);
static string decode(string);
static int getIndex(char);
static const char list[65];
};

const char Base64::list[65] = { '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','+','/','=' };

string Base64::encode(string s)
{
int len = s.size(), tmpLen;
string enStr;

tmpLen = len / 3 * 3;
for(int i = 0; i < tmpLen; i += 3)
{
enStr += Base64::list[s[i] >> 2];
enStr += Base64::list[(s[i] & 0x3) << 4 | (s[i + 1] >> 4)];
enStr += Base64::list[(s[i + 1] & 0xF) << 2 | (s[i + 2]) >> 6];
enStr += Base64::list[s[i + 2] & 0x3f];
}
if(tmpLen < len)
{
enStr += Base64::list[s[tmpLen] >> 2];
if(tmpLen + 1 == len)
{
enStr += Base64::list[((0x3 & s[tmpLen]) << 4)];
enStr += "=";
}
else
{
enStr += Base64::list[((0x3 & s[tmpLen]) << 4) | ((s[tmpLen + 1] & 0xF0) >> 4)];
enStr += Base64::list[(s[tmpLen + 1] & 0x0F) << 2];
}
enStr += "=";
}

return enStr;
}

string Base64::decode(string s)
{
string deStr;
int len = s.size() / 4 * 4; //avoid out of range
for(int i = 0; i < len; i += 4)
{
deStr += (char)((Base64::getIndex(s[i]) & 0x3F) << 2 | (Base64::getIndex(s[i + 1]) & 0x30) >> 4);
deStr += (char)((Base64::getIndex(s[i + 1]) & 0xF) << 4 | (Base64::getIndex(s[i + 2]) & 0x3C) >> 2);
deStr += (char)((Base64::getIndex(s[i + 2]) & 0x3) << 6 | (Base64::getIndex(s[i + 3]) & 0x3F));
}
return deStr;
}

int Base64::getIndex(char c)
{
for(int i = 0; i < 65; ++i)
if(c == Base64::list[i])
return i;
return -1;
}

#endif


测试代码:

#include <iostream>
#include "Base64.h"

using namespace std;

int main()
{
cout << Base64::encode("this is a test") << endl;
cout << Base64::decode(Base64::encode("this is a test")) << endl;
}


截图:



将迅雷链转成普通的链接:(迅雷链, 前面的thunder://是协议, 后面是将地址前面加上"AA", 末尾加上"ZZ", 由base64编码转换得到的,
链接只是随便找的一个, 我也不知道是什么内容, 仅用作测试。。);

thunder://QUFodHRwOi8vZDUuNTJlYm9vay5jb20vc2hlbGw4MTAvYm9va3MvemV4dWUvMjAwNjAxLzIwMDYxNjkzMTg0OTUucmFyWlo=/

去掉协议"thunder://"

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: