阅读DCMTK笔记-ofstd-Base64转换

        ofstd内部的Base64编码 

// Base64 translation table as described in RFC 2045 (MIME)
static const char enc_base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

OFCondition OFStandard::encodeBase64(STD_NAMESPACE ostream &out,
                                     const unsigned char *data,
                                     const size_t length,
                                     const size_t width)
{
    OFCondition status = EC_IllegalParameter;
    /* check data buffer to be encoded */
    if (data != NULL)
    {
        unsigned char c;
        size_t w = 0;
        /* iterate over all data elements */
        for (size_t i = 0; i < length; i++)
        {
            /* encode first 6 bits */
            out << enc_base64[(data[i] >> 2) & 0x3f];
            /* insert line break (if width > 0) */
            if (++w == width)
            {
                out << OFendl;
                w = 0;
            }
            /* encode remaining 2 bits of the first byte and 4 bits of the second byte */
            c = (data[i] << 4) & 0x3f;
            if (++i < length)
                c |= (data[i] >> 4) & 0x0f;
            out << enc_base64[c];
            /* insert line break (if width > 0) */
            if (++w == width)
            {
                out << OFendl;
                w = 0;
            }
            /* encode remaining 4 bits of the second byte and 2 bits of the third byte */
            if (i < length)
            {
                c = (data[i] << 2) & 0x3f;
                if (++i < length)
                    c |= (data[i] >> 6) & 0x03;
                out << enc_base64[c];
            } else {
                i++;
                /* append fill char */
                out << '=';
            }
            /* insert line break (if width > 0) */
            if (++w == width)
            {
                out << OFendl;
                w = 0;
            }
            /* encode remaining 6 bits of the third byte */
            if (i < length)
                out << enc_base64[data[i] & 0x3f];
            else /* append fill char */
                out << '=';
            /* insert line break (if width > 0) */
            if (++w == width)
            {
                out << OFendl;
                w = 0;
            }
        }
        /* flush stream */
        out.flush();
        status = EC_Normal;
    }
    return status;
}


const OFString &OFStandard::encodeBase64(const unsigned char *data,
                                         const size_t length,
                                         OFString &result,
                                         const size_t width)
{
    OFStringStream stream;
    /* call stream variant of base64 encoder */
    if (OFStandard::encodeBase64(stream, data, length, width).good())
    {
        stream << OFStringStream_ends;
        /* convert string stream into a character string */
        OFSTRINGSTREAM_GETSTR(stream, buffer_str)
        result.assign(buffer_str);
        OFSTRINGSTREAM_FREESTR(buffer_str)
    } else
        result.clear();
    return result;
}

        ofstd内部的Base64解码

// Base64 decoding table: maps #43..#122 to #0..#63 (255 means invalid)
static const unsigned char dec_base64[] =
  { 62, 255, 255, 255, 63,                                                                                  // '+' .. '/'
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61,                                                                 // '0' .. '9'
    255, 255, 255, 255, 255, 255, 255,                                                                      // ':' .. '@'
    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'
    255, 255, 255, 255, 255, 255,                                                                           // '[' .. '`'
    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'
  };

size_t OFStandard::decodeBase64(const OFString &data,
                                unsigned char *&result)
{
    size_t count = 0;
    /* search for fill char to determine the real length of the input string */
    const size_t fillPos = data.find('=');
    const size_t length = (fillPos != OFString_npos) ? fillPos : data.length();
    /* check data buffer to be decoded */
    if (length > 0)
    {
        /* allocate sufficient memory for the decoded data */
        result = new unsigned char[((length + 3) / 4) * 3];
        if (result != NULL)
        {
            unsigned char c1 = 0;
            unsigned char c2 = 0;
            /* iterate over all data elements */
            for (size_t i = 0; i < length; i++)
            {
                /* skip invalid characters and assign first decoded char */
                while ((i < length) && ((data.at(i) < '+') || (data.at(i) > 'z') || ((c1 = dec_base64[data.at(i) - '+']) > 63)))
                    i++;
                if (++i < length)
                {
                    /* skip invalid characters and assign second decoded char */
                    while ((i < length) && ((data.at(i) < '+') || (data.at(i) > 'z') || ((c2 = dec_base64[data.at(i) - '+']) > 63)))
                        i++;
                    if (i < length)
                    {
                        /* decode first byte */
                        result[count++] = OFstatic_cast(unsigned char, (c1 << 2) | ((c2 >> 4) & 0x3));
                        if (++i < length)
                        {
                            /* skip invalid characters and assign third decoded char */
                            while ((i < length) && ((data.at(i) < '+') || (data.at(i) > 'z') || ((c1 = dec_base64[data.at(i) - '+']) > 63)))
                                i++;
                            if (i < length)
                            {
                                /* decode second byte */
                                result[count++] = OFstatic_cast(unsigned char, ((c2 << 4) & 0xf0) | ((c1 >> 2) & 0xf));
                                if (++i < length)
                                {
                                    /* skip invalid characters and assign fourth decoded char */
                                    while ((i < length) && ((data.at(i) < '+') || (data.at(i) > 'z') || ((c2 = dec_base64[data.at(i) - '+']) > 63)))
                                        i++;
                                    /* decode third byte */
                                    if (i < length)
                                        result[count++] = OFstatic_cast(unsigned char, ((c1 << 6) & 0xc0) | c2);
                                }
                            }
                        }
                    }
                }
            }
            /* delete buffer if no data has been written to the output */
            if (count == 0)
                delete[] result;
        }
    } else
        result = NULL;
    return count;
}

自己实现的Base64编码;

将待处理的字符串,按照3个字节为一组进行处理;

void base64_encode(std::vector<unsigned char>& s, std::string& code) {
    code.clear();
    code.reserve((s.size() / 3 + 1) * 4);
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];
    int last_pos = s.size() / 3 * 3;
    for (size_t vs = 0; vs < last_pos; vs += 3) {
        memcpy(char_array_3, s.data() + vs, 3);
        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (int i = 0; i < 4; i++)
            code += base64_chars[char_array_4[i]];
    }

    int remainder_numb = s.size() % 3;
    if (remainder_numb != 0) {
        memset(char_array_3, 0, 3);
        memcpy(char_array_3, s.data() + last_pos, s.size() % 3);

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; j < remainder_numb + 1; j++)
            code += base64_chars[char_array_4[j]];
        code.append(4 - (remainder_numb + 1), '=');
    }
}

多线程处理Base64转换

        将一个待处理的字符串,根据3个字节为一块,N个块为一组;开启一个线程处理一组字符串转为base64字符串,处理完后append拼接在一起;

void base64_encode_mult(std::vector<unsigned char>& s, std::string& code) {
    code.clear();
    const int N = std::thread::hardware_concurrency() / 2;
    
    size_t num_block = s.size() / 3;
    size_t mid_pos = num_block / N * 3;

    std::vector<std::string> base64_strs;
    base64_strs.resize(N);
    std::vector<std::thread> th_list;
    using Func = void(*)(unsigned char * bytes_to_encode, unsigned int in_len, std::string& code);
    Func f1 = &base64_encode;

    for (int i = 0; i < N - 1; i++) {
        th_list.push_back(std::thread(f1, s.data() + mid_pos * i, mid_pos, std::ref(base64_strs[i])));
    }
    th_list.push_back(std::thread(f1, s.data() + mid_pos * (N - 1), s.size() - mid_pos * (N - 1), std::ref(base64_strs[N - 1])));

    for (std::size_t i = 0; i < th_list.size(); i++) {
        th_list[i].join();
        code.append(base64_strs[i]);
    }
}

void base64_encode(unsigned char * bytes_to_encode, unsigned int in_len, std::string& code) {
    code.clear();
    code.reserve((in_len / 3 + 1) * 4);
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];
    int last_pos = in_len / 3 * 3;
    for (size_t vs = 0; vs < last_pos; vs += 3) {
        memcpy(char_array_3, bytes_to_encode + vs, 3);
        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (int i = 0; i < 4; i++)
            code += base64_chars[char_array_4[i]];
    }

    int remainder_numb = in_len % 3;
    if (remainder_numb != 0) {
        memset(char_array_3, 0, 3);
        memcpy(char_array_3, bytes_to_encode + last_pos, in_len % 3);

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; j < remainder_numb + 1; j++)
            code += base64_chars[char_array_4[j]];
        code.append(4 - (remainder_numb + 1), '=');
    }
}

猜你喜欢

转载自blog.csdn.net/liushao1031177/article/details/123574961