• Base64


    Base64

    Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法

    代码实现(C++)

    /*
       base64.cpp and base64.h
       base64 encoding and decoding with C++.
       More information at
         https://renenyffenegger.ch/notes/development/Base64/Encoding-and-decoding-base-64-with-cpp
       Version: 2.rc.04 (release candidate)
       Copyright (C) 2004-2017, 2020 René Nyffenegger
       This source code is provided 'as-is', without any express or implied
       warranty. In no event will the author be held liable for any damages
       arising from the use of this software.
       Permission is granted to anyone to use this software for any purpose,
       including commercial applications, and to alter it and redistribute it
       freely, subject to the following restrictions:
       1. The origin of this source code must not be misrepresented; you must not
          claim that you wrote the original source code. If you use this source code
          in a product, an acknowledgment in the product documentation would be
          appreciated but is not required.
       2. Altered source versions must be plainly marked as such, and must not be
          misrepresented as being the original source code.
       3. This notice may not be removed or altered from any source distribution.
       René Nyffenegger rene.nyffenegger@adp-gmbh.ch
    */
    
    /**
     * Base64编解码
     * @file: Base64.cpp
     * @author: rancheng <rc4work@163.com>
     * @date: 2020-11-20
     */
    #include "Base64.h"
    
    namespace dev {
    
    static std::string base64Encode(BytesConstRef bs, const char* charSet, char padCh) {
        // 提前分配好内存
        auto len = bs.size();
        std::string ret((len + 2) / 3 * 4, '');
    
        // 每3个字节转换为4个Base64字符,不足的后面补充填充字符
        for (size_t i = 0, off = 0; i < len; i += 3) {
            ret[off++] = charSet[(bs[i] & 0xfc) >> 2];
            if (i + 1 < len) {
                ret[off++] = charSet[((bs[i] & 0x03) << 4) + ((bs[i + 1] & 0xf0) >> 4)];
                if (i + 2 < len) {
                    ret[off++] = charSet[((bs[i + 1] & 0x0f) << 2) + ((bs[i + 2] & 0xc0) >> 6)];
                    ret[off++] = charSet[bs[i + 2] & 0x3f];
                } else {
                    ret[off++] = charSet[(bs[i + 1] & 0x0f) << 2];
                    ret[off++] = padCh;
                }
            } else {
                ret[off++] = charSet[(bs[i] & 0x03) << 4];
                ret[off++] = padCh;
                ret[off++] = padCh;
            }
        }
    
        return ret;
    }
    
    // 将字节数组转换为Base64编码的字符串(标准字符集)
    std::string toBase64STD(BytesConstRef bs) {
        // 字符集
        static auto s_stdBase64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                       "abcdefghijklmnopqrstuvwxyz"
                                       "0123456789"
                                       "+/";
        // 填充字符
        static char s_stdPadCh = '=';
    
        return base64Encode(bs, s_stdBase64Chars, s_stdPadCh);
    }
    
    // 将字节数组转换为Base64编码的字符串(对url合法的字符集)
    std::string toBase64URL(BytesConstRef bs) {
        // 字符集
        static auto s_urlBase64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                       "abcdefghijklmnopqrstuvwxyz"
                                       "0123456789"
                                       "-_";
        // 填充字符
        static char s_urlPadCh = '=';
    
        return base64Encode(bs, s_urlBase64Chars, s_urlPadCh);
    }
    
    // base64字符转换为对应的int值(标准字符集)
    static int base64Ch2iSTD(int base64Ch) {
        if (base64Ch >= 'A' && base64Ch <= 'Z') return base64Ch - 'A';
        if (base64Ch >= 'a' && base64Ch <= 'z') return base64Ch - 'a' + ('Z' - 'A') + 1;
        if (base64Ch >= '0' && base64Ch <= '9') return base64Ch - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
        if (base64Ch == '+') return 62;
        if (base64Ch == '/') return 63;
        throw BadBase64Ch();
    }
    
    // base64字符转换为对应的int值(对url合法的字符集)
    static int base64Ch2iURL(int base64Ch) {
        if (base64Ch >= 'A' && base64Ch <= 'Z') return base64Ch - 'A';
        if (base64Ch >= 'a' && base64Ch <= 'z') return base64Ch - 'a' + ('Z' - 'A') + 1;
        if (base64Ch >= '0' && base64Ch <= '9') return base64Ch - '0' + ('Z' - 'A') + ('z' - 'a') + 2;
        if (base64Ch == '-') return 62;
        if (base64Ch == '_') return 63;
        throw BadBase64Ch();
    }
    
    using Base64Ch2i = int(*)(int);
    Bytes base64Decode(const std::string& base64, Base64Ch2i base64Ch2i, char padCh) {
        // 提前分配内存
        auto len = base64.size();
        Bytes ret((len + 3) / 4 * 3);
    
        // 每4个Base64字符转换为3个字节
        size_t off = 0;
        for (size_t i = 0; i < len; i += 4) {
            int one = base64Ch2i(base64[i]);
            // C++11标准保证str[str.size()]为''
            int two = base64Ch2i(base64[i + 1]);
            ret[off++] = (one << 2) + ((two & 0x30) >> 4);
            if (base64[i + 2] != padCh) {
                int three = base64Ch2i(base64[i + 2]);
                ret[off++] = ((two & 0x0f) << 4) + ((three & 0x3c) >> 2);
                if (base64[i + 3] != padCh) {
                    int four = base64Ch2i(base64[i + 3]);
                    ret[off++] = ((three & 0x03) << 6) + four;
                }
            }
        }
    
        ret.resize(off);
        return ret;
    }
    
    /**
     * 将Base64编码的字符串转换为字节数组
     * @param base64 Base64编码的字符串(标准字符集)
     * @return 对应的字节数组
     * @throw 遇到非法Base64字符抛出BadBase64Ch异常
     */
    Bytes fromBase64STD(const std::string& base64) {
        // 填充字符
        static char s_stdPadCh = '=';
    
        return base64Decode(base64, base64Ch2iSTD, s_stdPadCh);
    }
    
    
    
    /**
     * 将Base64编码的字符串转换为字节数组
     * @param base64 Base64编码的字符串(对url合法的字符集)
     * @return 对应的字节数组
     * @throw 遇到非法Base64字符抛出BadBase64Ch异常
     */
    Bytes fromBase64URL(const std::string& base64) {
        // 填充字符
        static char s_urlPadCh = '=';
    
        return base64Decode(base64, base64Ch2iURL, s_urlPadCh);
    }
    
    }   // namespace dev
    

    fromBase64函数中有一个小技巧,那就是在C++11中保证str[str.size()]返回字符''。

    URLSafe

    Base64编码后的字符,常用来作为URL参数传递。但有些情况下,编码后可能出现字符+和/,在URL中就不能直接作为参数。
    一般需要做URL Safe编码,就是把字符+和/分别变成-和_。

  • 相关阅读:
    Python基础—字符串
    Python基础—函数
    2019918练手爬虫日记
    python基础—列表
    Python urllib详解
    安装TesseractOCR显示无效的路径
    Sql server 关于ID突然自增问题解决方案
    Sql server 登陆后无法找不到数据库怎么解决
    Python常用语句及流程控制
    jquery cookie操作
  • 原文地址:https://www.cnblogs.com/HachikoT/p/13846685.html
Copyright © 2020-2023  润新知