Base64 加解密c/c++

Base64 其实不能算是真正加密解密的安全算法,因为这个东西大家都知道怎么解密,就没有意思了。不过登陆邮件服务器的时候,登陆密码要使用BASE64 加密,因此我将算法描述如下:
     Base64 核心算法:
  明文: hello
    对应的Ascii: 0x68, 0x65, 0x6c, 0x6c, 0x6f
    二进制:  01101000 01100101 011001101 011001101 01101111
    将明文按照每三个字节,变成4个字节的原则进行变化,首先将二进制中每次拿出6个bit 形成一个密码表索引,通过这个索引转到密文。
    例如上面的:
    二进制: 01101000 01100101 011001101 011001101 01101111
 6bit 变化: 011010 000110 010101 1001101 0110011 010110 111100(后面不足的上两个0)
  十六进制: 0x1a,  0x06,  0x15,  0x4d,   0x33,   0x16,  0x3c
那么在这个十六进制作为索引在下面的加密表中查处对应的密文,
  1. const unsigned char C_Base64::CodeTable[] = 
  2.     'A',  'B',  'C',  
  3.     'D',  'E',  'F'
  4.     'G',  'H',  'I'
  5.     'J',  'K',  'L'
  6.     'M',  'N',  'O'
  7.     'P',  'Q',  'R',  
  8.     'S',  'T',  'U',  
  9.     'V',  'W',  'X'
  10.     'Y',  'Z',  'a'
  11.     'b',  'c',  'd'
  12.     'e',  'f',  'g'
  13.     'h',  'i',  'j'
  14.     'k',  'l',  'm'
  15.     'n',  'o',  'p'
  16.     'q',  'r',  's'
  17.     't',  'u',  'v'
  18.     'w',  'x',  'y'
  19.     'z',  '0',  '1',
  20.     '2',  '3',  '4'
  21.     '5',  '6',  '7',
  22.     '8',  '9',  '+',
  23.     '/'
  24. };
  在这个表中0x1a,对应的是:'a'。
一次查出为aGVsbG8,很明显不够4的整数倍,那么再补一个特殊字符"=",因此密文: aGVsbG8=
就是说在不够的情况下,可能要补一个或者二个特殊的字符"=",凑够4的整数倍。

因此C++的实现源码如下:
  1. // _Base64.h: interface for the C_Base64 class.
  2. //
  3. //
  4. #if !defined(AFX__BASE64_H__D718F826_7489_43E8_B5EF_64ED8EBBCD7E__INCLUDED_)
  5. #define AFX__BASE64_H__D718F826_7489_43E8_B5EF_64ED8EBBCD7E__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #pragma warning(disable: 4786)
  10. #include <map>
  11. using namespace std;
  12. class C_Base64  
  13. {
  14. public:
  15.     C_Base64();
  16.      virtual ~C_Base64();
  17.      bool EncodeBase64(const unsigned char *Source, unsigned int nNum, unsigned char *Dest, unsigned int &nNumout);
  18.      bool DecodeBase64(const unsigned char *Source, unsigned int nNum, unsigned char *Dest, unsigned int &nNumout);
  19. public:
  20.     typedef unsigned char BYTE;
  21.     typedef map<BYTEBYTE> DECODETYPE;
  22. private:
  23.     bool Initial();
  24. private:
  25.     static const unsigned char CodeTable[] ;
  26.     DECODETYPE DecodeTable;
  27.     
  28. };
  29. #endif // !defined(AFX__BASE64_H__D718F826_7489_43E8_B5EF_64ED8EBBCD7E__INCLUDED_)
cPP 文件
  1. // _Base64.cpp: implementation of the C_Base64 class.
  2. //
  3. //
  4. #include "stdafx.h"
  5. #include "_Base64.h"
  6. #include <assert.h>
  7. //
  8. // Construction/Destruction
  9. //
  10. const unsigned char C_Base64::CodeTable[] = 
  11.     'A',  'B',  'C',  
  12.     'D',  'E',  'F'
  13.     'G',  'H',  'I'
  14.     'J',  'K',  'L'
  15.     'M',  'N',  'O'
  16.     'P',  'Q',  'R',  
  17.     'S',  'T',  'U',  
  18.     'V',  'W',  'X'
  19.     'Y',  'Z',  'a'
  20.     'b',  'c',  'd'
  21.     'e',  'f',  'g'
  22.     'h',  'i',  'j'
  23.     'k',  'l',  'm'
  24.     'n',  'o',  'p'
  25.     'q',  'r',  's'
  26.     't',  'u',  'v'
  27.     'w',  'x',  'y'
  28.     'z',  '0',  '1',
  29.     '2',  '3',  '4'
  30.     '5',  '6',  '7',
  31.     '8',  '9',  '+',
  32.     '/'
  33. };
  34. bool C_Base64::Initial()
  35. {
  36.     BYTE nIndex = 'A';
  37.     BYTE nCount = 0;
  38.     
  39.     // 'A' - 'Z'
  40.     for (nIndex = 'A'; nIndex <= 'Z'; ++nIndex)
  41.     {
  42.         DecodeTable.insert(C_Base64::DECODETYPE::value_type(nIndex, nCount));
  43.         ++nCount;
  44.     }
  45.     // 'a' - 'z'
  46.     for (nIndex = 'a'; nIndex <= 'z'; ++nIndex)
  47.     {
  48.         DecodeTable.insert(C_Base64::DECODETYPE::value_type(nIndex, nCount));
  49.         ++nCount;
  50.     }
  51.     // '0' - '9'
  52.     for (nIndex = '0'; nIndex <= '9'; ++nIndex)
  53.     {
  54.         DecodeTable.insert(C_Base64::DECODETYPE::value_type(nIndex, nCount));
  55.         ++nCount;
  56.     }
  57.     // '+'
  58.     DecodeTable.insert(C_Base64::DECODETYPE::value_type('+', nCount));
  59.     ++nCount;
  60.     
  61.     // '/'
  62.     DecodeTable.insert(C_Base64::DECODETYPE::value_type('/', nCount));
  63.     return true;
  64. }
  65. C_Base64::C_Base64()
  66. {
  67.   Initial();
  68. }
  69. C_Base64::~C_Base64()
  70. {
  71. }
  72. bool C_Base64::EncodeBase64(const unsigned char *Source, unsigned int nNum, 
  73.                             unsigned char *Dest,  unsigned int &nNumout)
  74. {
  75.     unsigned int nGroup = nNum / 3;
  76.     const BYTE *pSource = Source;
  77.     for (unsigned int nIndex = 0; nIndex < nGroup; ++nIndex)
  78.     {
  79.         BYTE source1 = *(pSource + nIndex * 3);
  80.         BYTE source2 = *(pSource + nIndex * 3 + 1);
  81.         BYTE source3 = *(pSource + nIndex * 3 + 2);
  82.         BYTE code1 = (source1 >> 2) & 0x3f; 
  83.         BYTE code2 = ((source1 << 4) | (source2 >> 4)) & 0x3f;
  84.         BYTE code3 = ((source2 << 2) | (source3 >> 6)) & 0x3f;
  85.         BYTE code4 = source3 & 0x3f;
  86.         *(Dest + nIndex * 4) = CodeTable[code1];
  87.         *(Dest + nIndex * 4 + 1) = CodeTable[code2];
  88.         *(Dest + nIndex * 4 + 2) = CodeTable[code3];
  89.         *(Dest + nIndex * 4 + 3) = CodeTable[code4];
  90.     }
  91.     unsigned int nRest = nNum % 3;
  92.     if ( 1 == nRest)
  93.     {
  94.         BYTE source1 = *(pSource + (nGroup)  * 3 + 0);
  95.         BYTE code1 = (source1 >> 2) & 0x3f; 
  96.         BYTE code2 = (source1 << 4) & 0x3f;
  97.         BYTE code3 = '=';
  98.         BYTE code4 = '=';
  99.         *(Dest + nGroup  * 4 + 0) = CodeTable[code1];
  100.         *(Dest + nGroup  * 4 + 1) = CodeTable[code2];
  101.         *(Dest + nGroup  * 4 + 2) = code3;
  102.         *(Dest + nGroup  * 4 + 3) = code4;
  103.     
  104.     }
  105.     else if (2 == nRest)
  106.     {
  107.         BYTE source1 = *(pSource + (nGroup)  * 3 + 0);
  108.         BYTE source2 = *(pSource + (nGroup)  * 3 + 1);
  109.         BYTE code1 = (source1 >> 2) & 0x3f; 
  110.         BYTE code2 = ((source1 << 4) | (source2 >> 4)) & 0x3f;
  111.         BYTE code3 = (source2 << 2)  & 0x3f;
  112.         BYTE code4 = '=';
  113.         *(Dest + nGroup  * 4 + 0) = CodeTable[code1];
  114.         *(Dest + nGroup  * 4 + 1) = CodeTable[code2];
  115.         *(Dest + nGroup  * 4 + 2) = CodeTable[code3];
  116.         *(Dest + nGroup  * 4 + 3) = code4;
  117.     }
  118.     nNumout = nGroup * 4;
  119.     if (nRest != 0)
  120.     {
  121.         nNumout += 4;
  122.     }
  123.     
  124.     return true;
  125. }
  126. bool C_Base64::DecodeBase64(const unsigned char *Source, 
  127.                             unsigned int nNum, unsigned char *Dest,
  128.                             unsigned int &nNumout)
  129. {
  130.     assert(nNum % 4 == 0);
  131.     if (nNum % 4 != 0)
  132.     {
  133.         return false;
  134.     }
  135.     unsigned int nGroup = nNum / 4;
  136.     unsigned int nIndex = 0;
  137.     const BYTE *pSource = Source;
  138.     for (nIndex = 0; nIndex < nGroup - 1; ++nIndex)
  139.     {
  140.         BYTE code1 = *(pSource + nIndex * 4 + 0);
  141.         BYTE code2 = *(pSource + nIndex * 4 + 1);
  142.         BYTE code3 = *(pSource + nIndex * 4 + 2);
  143.         BYTE code4 = *(pSource + nIndex * 4 + 3);
  144.         BYTE dcode1 = DecodeTable[code1];
  145.         BYTE dcode2 = DecodeTable[code2];
  146.         BYTE dcode3 = DecodeTable[code3];
  147.         BYTE dcode4 = DecodeTable[code4];
  148.         *(Dest + nIndex  * 3 + 0) = (dcode1 << 2 | ((dcode2 >> 4) & 0x3)) & 0xff;
  149.         *(Dest + nIndex  * 3 + 1) = ((dcode2 << 4) | (dcode3 >> 2)) & 0xff;
  150.         *(Dest + nIndex  * 3 + 2) = ((dcode3 << 6) | (dcode4 & 0x3f))& 0xff;
  151.     }
  152.     unsigned int OutBytes = 3 * nGroup;
  153.     // last group data
  154.     {
  155.         BYTE code1 = *(pSource + (nGroup - 1) * 4 + 0);
  156.         BYTE code2 = *(pSource + (nGroup - 1) * 4 + 1);
  157.         BYTE code3 = *(pSource + (nGroup - 1) * 4 + 2);
  158.         BYTE code4 = *(pSource + (nGroup - 1) * 4 + 3);
  159.         if (code3 == '=' && code4 == '=')
  160.         {
  161.             BYTE dcode1 = DecodeTable[code1];
  162.             BYTE dcode2 = DecodeTable[code2];
  163.             *(Dest + (nGroup - 1)  * 3 + 0) = (dcode1 << 2 | ((dcode2 >> 4) & 0x3)) & 0xff;
  164.             
  165.             OutBytes -= 2;
  166.         }
  167.         else if (code4 == '=')
  168.         {
  169.             BYTE dcode1 = DecodeTable[code1];
  170.             BYTE dcode2 = DecodeTable[code2];
  171.             BYTE dcode3 = DecodeTable[code3];
  172.             *(Dest + (nGroup - 1)  * 3 + 0) = (dcode1 << 2 | ((dcode2 >> 4) & 0x3)) & 0xff;
  173.             *(Dest + (nGroup - 1)  * 3 + 1) = ((dcode2 << 4) | (dcode3 >> 2)) & 0xff;
  174.             OutBytes -= 1;
  175.             
  176.         }
  177.     }
  178.    nNumout = OutBytes;
  179.     return true;
  180. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值