Base64算法的C++实现

简介:

Base64用途

1.用于对SOHO级路由器(网关设备)管理员帐户密码的加密

2.流媒体网站对于播放的流媒体文件的路径的加密

3.迅雷等下载软件对下载链接地址的加密

Base64算法

Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。

Base64

函数:

unsigned int CreateMatchingEncodingBuffer (unsigned int p_InputByteCountchar** p_ppEncodingBuffer);

创建匹配于编码的缓存空间。参数:1输入字节数,2进行编码需要的缓存空间;返回值:缓存空间大小。

unsigned int CreateMatchingDecodingBuffer (charp_pInputBufferStringchar** p_ppDecodingBuffer);

创建匹配于解码的缓存空间。参数:1解码对象缓存,2进行解码需要的缓存空间;返回值:缓存空间大小。

void EncodeBuffer (charp_pInputBufferunsigned int p_InputBufferLengthcharp_pOutputBufferString);

进行编码。参数:1明文,2明文长度,3密文输出。

unsigned int DecodeBuffer (charp_pInputBufferStringcharp_pOutputBuffer);

进行解码。参数:1密文,2明文;返回值:明文长度

C++实现:

头文件:

复制代码
/************************************************
*                        *
* CBase64.h                    *
* Base 64 de- and encoding class        *
*                        *
* ============================================  *
*                        *
* This class was written on 28.05.2003        *
* by Jan Raddatz [jan-raddatz@web.de]        *
*                        *
* ============================================  *
*                        *
* Copyright (c) by Jan Raddatz            *
* This class was published @ codeguru.com    *
* 28.05.2003                    *
*                        *
************************************************/

#pragma once

#include <afx.h>
#include <stdlib.h>
#include <math.h>
#include <memory.h>
const static unsigned int MAX_LINE_LENGTH = 76;

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

const static char BASE64_DEALPHABET [128] = 
{
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, //   0 -   9
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, //  10 -  19
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, //  20 -  29
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, //  30 -  39
    0,  0,  0, 62,  0,  0,  0, 63, 52, 53, //  40 -  49
    54, 55, 56, 57, 58, 59, 60, 61,  0,  0, //  50 -  59
    0, 61,  0,  0,  0,  0,  1,  2,  3,  4, //  60 -  69
    5,  6,  7,  8,  9, 10, 11, 12, 13, 14, //  70 -  79
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //  80 -  89
    25,  0,  0,  0,  0,  0,  0, 26, 27, 28, //  90 -  99
    29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // 100 - 109
    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, // 110 - 119
    49, 50, 51,  0,  0,  0,  0,  0        // 120 - 127
};

enum
{
    UNABLE_TO_OPEN_INPUT_FILE,
    UNABLE_TO_OPEN_OUTPUT_FILE,
    UNABLE_TO_CREATE_OUTPUTBUFFER
};

class CBase64
{
public:
    CBase64 ();

    unsigned int CalculateRecquiredEncodeOutputBufferSize (unsigned int p_InputByteCount);
    unsigned int CalculateRecquiredDecodeOutputBufferSize (char* p_pInputBufferString);

    void EncodeByteTriple  (char* p_pInputBuffer, unsigned int InputCharacters, char* p_pOutputBuffer);
    unsigned int DecodeByteQuartet (char* p_pInputBuffer, char* p_pOutputBuffer);

    void EncodeBuffer (char* p_pInputBuffer, unsigned int p_InputBufferLength, char*p_pOutputBufferString);
    unsigned int DecodeBuffer (char* p_pInputBufferString, char* p_pOutputBuffer);

    unsigned int CreateMatchingEncodingBuffer (unsigned int p_InputByteCount, char** p_ppEncodingBuffer);
    unsigned int CreateMatchingDecodingBuffer (char* p_pInputBufferString, char** p_ppDecodingBuffer);

    unsigned int EncodeFile (char* p_pSourceFileName, char* p_pEncodedFileName);
    unsigned int DecodeFile (char* p_pSourceFileName, char* p_pDecodedFileName);
};
复制代码

cpp文件:

复制代码
/************************************************
*                        *
* CBase64.cpp                    *
* Base 64 de- and encoding class        *
*                        *
* ============================================  *
*                        *
* This class was written on 28.05.2003        *
* by Jan Raddatz [jan-raddatz@web.de]        *
*                        *
* ============================================  *
*                        *
* Copyright (c) by Jan Raddatz            *
* This class was published @ codeguru.com    *
* 28.05.2003                    *
*                        *
************************************************/
#include "stdafx.h"
#include "CBase64.h"


CBase64::CBase64 ()
{
}

unsigned int CBase64::CalculateRecquiredEncodeOutputBufferSize (unsigned int p_InputByteCount)
{
    div_t result = div (p_InputByteCount, 3);

    unsigned int RecquiredBytes = 0;
    if (result.rem == 0)
    {
        // Number of encoded characters
        RecquiredBytes = result.quot * 4;

        // CRLF -> "\r\n" each 76 characters
        result = div (RecquiredBytes, 76);
        RecquiredBytes += result.quot * 2;

        // Terminating null for the Encoded String
        RecquiredBytes += 1;

        return RecquiredBytes;
    }
    else
    {
        // Number of encoded characters
        RecquiredBytes = result.quot * 4 + 4;

        // CRLF -> "\r\n" each 76 characters
        result = div (RecquiredBytes, 76);
        RecquiredBytes += result.quot * 2;

        // Terminating null for the Encoded String
        RecquiredBytes += 1;

        return RecquiredBytes;
    }
}

unsigned int CBase64::CalculateRecquiredDecodeOutputBufferSize (char* p_pInputBufferString)
{
    unsigned int BufferLength = strlen (p_pInputBufferString);

    div_t result = div (BufferLength, 4);

    if (p_pInputBufferString [BufferLength - 1] != '=')
    {
        return result.quot * 3;
    }
    else
    {
        if (p_pInputBufferString [BufferLength - 2] == '=')
        {
            return result.quot * 3 - 2;
        }
        else
        {
            return result.quot * 3 - 1;
        }
    }
}

void CBase64::EncodeByteTriple (char* p_pInputBuffer, unsigned int InputCharacters, char* p_pOutputBuffer)
{
    unsigned int mask = 0xfc000000;
    unsigned int buffer = 0;


    char* temp = (char*) &buffer;
    temp [3] = p_pInputBuffer [0];
    if (InputCharacters > 1)
        temp [2] = p_pInputBuffer [1];
    if (InputCharacters > 2)
        temp [1] = p_pInputBuffer [2];

    switch (InputCharacters)
    {
    case 3:
        {
            p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [2] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [3] = BASE64_ALPHABET [(buffer & mask) >> 26];
            break;
        }
    case 2:
        {
            p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [2] = BASE64_ALPHABET [(buffer & mask) >> 26];
            p_pOutputBuffer [3] = '=';
            break;
        }
    case 1:
        {
            p_pOutputBuffer [0] = BASE64_ALPHABET [(buffer & mask) >> 26];
            buffer = buffer << 6;
            p_pOutputBuffer [1] = BASE64_ALPHABET [(buffer & mask) >> 26];
            p_pOutputBuffer [2] = '=';
            p_pOutputBuffer [3] = '=';
            break;
        }
    }
}

unsigned int CBase64::DecodeByteQuartet (char* p_pInputBuffer, char* p_pOutputBuffer)
{
    unsigned int buffer = 0;

    if (p_pInputBuffer[3] == '=')
    {
        if (p_pInputBuffer[2] == '=')
        {
            buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
            buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
            buffer = buffer << 14;

            char* temp = (char*) &buffer;
            p_pOutputBuffer [0] = temp [3];

            return 1;
        }
        else
        {
            buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
            buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
            buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[2]]) << 6;
            buffer = buffer << 8;

            char* temp = (char*) &buffer;
            p_pOutputBuffer [0] = temp [3];
            p_pOutputBuffer [1] = temp [2];

            return 2;
        }
    }
    else
    {
        buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[0]]) << 6;
        buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[1]]) << 6;
        buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[2]]) << 6;
        buffer = (buffer | BASE64_DEALPHABET [p_pInputBuffer[3]]) << 6; 
        buffer = buffer << 2;

        char* temp = (char*) &buffer;
        p_pOutputBuffer [0] = temp [3];
        p_pOutputBuffer [1] = temp [2];
        p_pOutputBuffer [2] = temp [1];

        return 3;
    }

    return -1;
}

void CBase64::EncodeBuffer(char* p_pInputBuffer, unsigned int p_InputBufferLength, char* p_pOutputBufferString)
{
    unsigned int FinishedByteQuartetsPerLine = 0;
    unsigned int InputBufferIndex  = 0;
    unsigned int OutputBufferIndex = 0;

    memset (p_pOutputBufferString, 0, CalculateRecquiredEncodeOutputBufferSize (p_InputBufferLength));

    while (InputBufferIndex < p_InputBufferLength)
    {
        if (p_InputBufferLength - InputBufferIndex <= 2)
        {
            FinishedByteQuartetsPerLine ++;
            EncodeByteTriple (p_pInputBuffer + InputBufferIndex, p_InputBufferLength - InputBufferIndex, p_pOutputBufferString + OutputBufferIndex);
            break;
        }
        else
        {
            FinishedByteQuartetsPerLine++;
            EncodeByteTriple (p_pInputBuffer + InputBufferIndex, 3, p_pOutputBufferString + OutputBufferIndex);
            InputBufferIndex  += 3;
            OutputBufferIndex += 4;
        }

        if (FinishedByteQuartetsPerLine == 19)
        {
            p_pOutputBufferString [OutputBufferIndex  ] = '\r';
            p_pOutputBufferString [OutputBufferIndex+1] = '\n';
            p_pOutputBufferString += 2;
            FinishedByteQuartetsPerLine = 0;
        }
    }
}

unsigned int CBase64::DecodeBuffer (char* p_pInputBufferString, char* p_pOutputBuffer)
{
    unsigned int InputBufferIndex  = 0;
    unsigned int OutputBufferIndex = 0;
    unsigned int InputBufferLength = strlen (p_pInputBufferString);

    char ByteQuartet [4];

    while (InputBufferIndex < InputBufferLength)
    {
        for (int i = 0; i < 4; i++)
        {
            ByteQuartet [i] = p_pInputBufferString [InputBufferIndex];

            // Ignore all characters except the ones in BASE64_ALPHABET
            if ((ByteQuartet [i] >= 48 && ByteQuartet [i] <=  57) ||
                (ByteQuartet [i] >= 65 && ByteQuartet [i] <=  90) ||
                (ByteQuartet [i] >= 97 && ByteQuartet [i] <= 122) ||
                ByteQuartet [i] == '+' || ByteQuartet [i] == '/' || ByteQuartet [i] == '=')
            {
            }
            else
            {
                // Invalid character
                i--;
            }

            InputBufferIndex++;
        }

        OutputBufferIndex += DecodeByteQuartet (ByteQuartet, p_pOutputBuffer + OutputBufferIndex);
    }

    // OutputBufferIndex gives us the next position of the next decoded character
    // inside our output buffer and thus represents the number of decoded characters
    // in our buffer.
    return OutputBufferIndex;
}

unsigned int CBase64::CreateMatchingEncodingBuffer (unsigned int p_InputByteCount, char** p_ppEncodingBuffer)
{
    unsigned int Size = CalculateRecquiredEncodeOutputBufferSize (p_InputByteCount);
    (*p_ppEncodingBuffer) = (char*) malloc (Size);
    memset (*p_ppEncodingBuffer, 0, Size);
    return Size;
}

unsigned int CBase64::CreateMatchingDecodingBuffer (char* p_pInputBufferString, char** p_ppDecodingBuffer)
{
    unsigned int Size = CalculateRecquiredDecodeOutputBufferSize (p_pInputBufferString);
    (*p_ppDecodingBuffer) = (char*) malloc (Size+1);
    memset (*p_ppDecodingBuffer, 0, Size+1);
    return Size+1;
}

unsigned int CBase64::EncodeFile (char* p_pSourceFileName, char* p_pEncodedFileName)
{
    CFile InputFile;
    CFile OutputFile;

    if (!InputFile.Open (p_pSourceFileName, CFile::modeRead))
        return UNABLE_TO_OPEN_INPUT_FILE;

    if (!OutputFile.Open (p_pEncodedFileName, CFile::modeCreate|CFile::modeWrite))
        return UNABLE_TO_OPEN_OUTPUT_FILE;

    char InputBuffer [19 * 3];
    char* pOutputBuffer;
    CreateMatchingEncodingBuffer (sizeof (InputBuffer), &pOutputBuffer);

    if (pOutputBuffer == 0)
        return UNABLE_TO_CREATE_OUTPUTBUFFER;

    unsigned int ReadBytes = 0;
    while ((ReadBytes = InputFile.Read (InputBuffer, sizeof (InputBuffer))) != 0)
    {
        EncodeBuffer (InputBuffer, ReadBytes, pOutputBuffer);
        OutputFile.Write (pOutputBuffer, strlen (pOutputBuffer));
    }

    OutputFile.Flush ();
    OutputFile.Close ();
    InputFile.Close  ();

    return 0;
}

unsigned int CBase64::DecodeFile (char* p_pSourceFileName, char* p_pDecodedFileName)
{
    CStdioFile    InputFile;
    CFile        OutputFile;

    if (!InputFile.Open (p_pSourceFileName, CFile::modeRead))
        return UNABLE_TO_OPEN_INPUT_FILE;

    if (!OutputFile.Open (p_pDecodedFileName, CFile::modeCreate|CFile::modeWrite))
        return UNABLE_TO_OPEN_OUTPUT_FILE;

    CString InputBuffer;
    char    OutputBuffer[64];

    unsigned int ReadBytes = 0;
    while ((ReadBytes = InputFile.ReadString (InputBuffer)) != 0)
    {
        InputBuffer.Remove ('\r');
        InputBuffer.Remove ('\n');
        unsigned int DecodedBytes = DecodeBuffer ((LPTSTR) (LPCTSTR) InputBuffer, OutputBuffer);
        OutputFile.Write (&OutputBuffer [0], DecodedBytes);
    }

    OutputFile.Flush ();
    OutputFile.Close ();
    InputFile.Close  ();

    return 0;
}
复制代码

 

参考:

1.Base64-维基百科( http://zh.wikipedia.org/wiki/Base64
2. BASE 64 Decoding and Encoding Class  (http://www.codeguru.com/cpp/cpp/algorithms/article.php/c5099 )
 
作者: 阿凡卢
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

相关文章
|
12天前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
4天前
|
算法 数据处理 C++
C++一分钟之-迭代器与算法
【6月更文挑战第21天】C++ STL的迭代器统一了容器元素访问,分为多种类型,如输入、输出、前向、双向和随机访问。迭代器使用时需留意失效和类型匹配。STL算法如查找、排序、复制要求特定类型的迭代器,注意容器兼容性和返回值处理。适配器和算法组合增强灵活性,但过度使用可能降低代码可读性。掌握迭代器和算法能提升编程效率和代码质量。
22 3
|
9天前
|
算法 前端开发 Linux
【常用技巧】C++ STL容器操作:6种常用场景算法
STL在Linux C++中使用的非常普遍,掌握并合适的使用各种容器至关重要!
33 10
|
26天前
|
缓存 负载均衡 算法
C++如何实现一致性算法
一致性哈希是一种用于分布式系统的负载均衡算法,旨在减少服务器增减导致的数据迁移。当有N台服务器时,通过哈希环将请求均匀分布到每台服务器,每台处理N/1的请求。若使用缓存如Redis,可进一步处理高并发场景。算法将哈希值空间视为环形,服务器和请求哈希后定位到环上,按顺时针方向找到第一台服务器作为负载目标。提供的C++代码实现了MD5哈希函数,以及一致性哈希算法的物理节点、虚拟节点和算法本身,以实现节点的添加、删除和请求映射。
20 1
C++如何实现一致性算法
|
19天前
|
存储 算法 Cloud Native
C++ bcrypt算法 字符串加密,亲测有效
C++ bcrypt算法 字符串加密,亲测有效
|
1天前
|
算法 前端开发 安全
C++算法模板
C++算法模板
3 0
|
1月前
|
人工智能 算法 C++
c++算法学习笔记 (17) 质数
c++算法学习笔记 (17) 质数
|
1月前
|
算法 C++
c++算法学习笔记 (15) 单调栈与单调队列
c++算法学习笔记 (15) 单调栈与单调队列
|
1月前
|
算法 C++
c++算法学习笔记 (13) 链表
c++算法学习笔记 (13) 链表
|
1月前
|
算法 C++
c++算法学习笔记 (12) 区间合并
c++算法学习笔记 (12) 区间合并