How do I base64 encode (decode) in C?

后端 未结 17 1493
孤城傲影
孤城傲影 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:33

    Here's my solution using OpenSSL.

    /* A BASE-64 ENCODER AND DECODER USING OPENSSL */
    #include 
    #include  //Only needed for strlen().
    
    char *base64encode (const void *b64_encode_this, int encode_this_many_bytes){
        BIO *b64_bio, *mem_bio;      //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
        BUF_MEM *mem_bio_mem_ptr;    //Pointer to a "memory BIO" structure holding our base64 data.
        b64_bio = BIO_new(BIO_f_base64());                      //Initialize our base64 filter BIO.
        mem_bio = BIO_new(BIO_s_mem());                           //Initialize our memory sink BIO.
        BIO_push(b64_bio, mem_bio);            //Link the BIOs by creating a filter-sink BIO chain.
        BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);  //No newlines every 64 characters or less.
        BIO_write(b64_bio, b64_encode_this, encode_this_many_bytes); //Records base64 encoded data.
        BIO_flush(b64_bio);   //Flush data.  Necessary for b64 encoding, because of pad characters.
        BIO_get_mem_ptr(mem_bio, &mem_bio_mem_ptr);  //Store address of mem_bio's memory structure.
        BIO_set_close(mem_bio, BIO_NOCLOSE);   //Permit access to mem_ptr after BIOs are destroyed.
        BIO_free_all(b64_bio);  //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
        BUF_MEM_grow(mem_bio_mem_ptr, (*mem_bio_mem_ptr).length + 1);   //Makes space for end null.
        (*mem_bio_mem_ptr).data[(*mem_bio_mem_ptr).length] = '\0';  //Adds null-terminator to tail.
        return (*mem_bio_mem_ptr).data; //Returns base-64 encoded data. (See: "buf_mem_st" struct).
    }
    
    char *base64decode (const void *b64_decode_this, int decode_this_many_bytes){
        BIO *b64_bio, *mem_bio;      //Declares two OpenSSL BIOs: a base64 filter and a memory BIO.
        char *base64_decoded = calloc( (decode_this_many_bytes*3)/4+1, sizeof(char) ); //+1 = null.
        b64_bio = BIO_new(BIO_f_base64());                      //Initialize our base64 filter BIO.
        mem_bio = BIO_new(BIO_s_mem());                         //Initialize our memory source BIO.
        BIO_write(mem_bio, b64_decode_this, decode_this_many_bytes); //Base64 data saved in source.
        BIO_push(b64_bio, mem_bio);          //Link the BIOs by creating a filter-source BIO chain.
        BIO_set_flags(b64_bio, BIO_FLAGS_BASE64_NO_NL);          //Don't require trailing newlines.
        int decoded_byte_index = 0;   //Index where the next base64_decoded byte should be written.
        while ( 0 < BIO_read(b64_bio, base64_decoded+decoded_byte_index, 1) ){ //Read byte-by-byte.
            decoded_byte_index++; //Increment the index until read of BIO decoded data is complete.
        } //Once we're done reading decoded data, BIO_read returns -1 even though there's no error.
        BIO_free_all(b64_bio);  //Destroys all BIOs in chain, starting with b64 (i.e. the 1st one).
        return base64_decoded;        //Returns base-64 decoded data with trailing null terminator.
    }
    
    /*Here's one way to base64 encode/decode using the base64encode() and base64decode functions.*/
    int main(void){
        char data_to_encode[] = "Base64 encode this string!";  //The string we will base-64 encode.
    
        int bytes_to_encode = strlen(data_to_encode); //Number of bytes in string to base64 encode.
        char *base64_encoded = base64encode(data_to_encode, bytes_to_encode);   //Base-64 encoding.
    
        int bytes_to_decode = strlen(base64_encoded); //Number of bytes in string to base64 decode.
        char *base64_decoded = base64decode(base64_encoded, bytes_to_decode);   //Base-64 decoding.
    
        printf("Original character string is: %s\n", data_to_encode);  //Prints our initial string.
        printf("Base-64 encoded string is: %s\n", base64_encoded);  //Prints base64 encoded string.
        printf("Base-64 decoded string is: %s\n", base64_decoded);  //Prints base64 decoded string.
    
        free(base64_encoded);                //Frees up the memory holding our base64 encoded data.
        free(base64_decoded);                //Frees up the memory holding our base64 decoded data.
    }
    

提交回复
热议问题