How do I base64 encode (decode) in C?

后端 未结 17 1733
孤城傲影
孤城傲影 2020-11-22 06:27

I have binary data in an unsigned char variable. I need to convert them to PEM base64 in c. I looked in openssl library but i could not find any function. Does any body have

17条回答
  •  心在旅途
    2020-11-22 06:42

    Here is an optimized version of encoder for the accepted answer, that also supports line-breaking for MIME and other protocols (simlar optimization can be applied to the decoder):

     char *base64_encode(const unsigned char *data,
                        size_t input_length,
                        size_t *output_length,
                        bool addLineBreaks)
    
        *output_length = 4 * ((input_length + 2) / 3);
        if (addLineBreaks) *output_length += *output_length / 38; //  CRLF after each 76 chars
    
        char *encoded_data = malloc(*output_length);
        if (encoded_data == NULL) return NULL;
    
        UInt32 octet_a;
        UInt32 octet_b;
        UInt32 octet_c;
        UInt32 triple;
        int lineCount = 0;
        int sizeMod = size - (size % 3); // check if there is a partial triplet
        // adding all octet triplets, before partial last triplet
        for (; offset < sizeMod; ) 
        {
            octet_a = data[offset++];
            octet_b = data[offset++];
            octet_c = data[offset++];
    
            triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
    
            encoded_data[mBufferPos++] = encoding_table[(triple >> 3 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 2 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 1 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 0 * 6) & 0x3F];
            if (addLineBreaks)
            {
                if (++lineCount == 19)
                {
                    encoded_data[mBufferPos++] = 13;
                    encoded_data[mBufferPos++] = 10;
                    lineCount = 0;
                }
            }
        }
    
        // last bytes
        if (sizeMod < size)
        {
            octet_a = data[offset++]; // first octect always added
            octet_b = offset < size ? data[offset++] : (UInt32)0; // conditional 2nd octet
            octet_c = (UInt32)0; // last character is definitely padded
    
            triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
    
            encoded_data[mBufferPos++] = encoding_table[(triple >> 3 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 2 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 1 * 6) & 0x3F];
            encoded_data[mBufferPos++] = encoding_table[(triple >> 0 * 6) & 0x3F];
    
            // add padding '='
            sizeMod = size % 3; 
            // last character is definitely padded
            encoded_data[mBufferPos - 1] = (byte)'=';
            if (sizeMod == 1) encoded_data[mBufferPos - 2] = (byte)'=';
        }
     }
    

提交回复
热议问题