用OpenSSL 做Base64 编解码(C++)
main.cpp
[cpp] view plaincopy
1. #include
9. char * Base64Encode(const char* input, int length, bool with_new_line); 10. char * Base64Decode(char* input, int length, bool with_new_line); 11.
12. int main(int argc, char* argv[]) 13. {
14. cout << \; 15. string option; 16. cin >> option;
17. bool with_new_line = ( (\ == option || \ == option) ? true : false )
; 18.
19. string enc_input = \
ter, political scientist, diplomat, and businessman. A recipient of the Nobel Peace Prize, he served as National Security Advisor and later concurrently as Secretary of State in the administrations of Presidents Richard Nixon and Gerald Ford.\; 20.
21. cout << endl << \ << endl << \ << enc_input << \ << e
ndl << endl; 22.
23. char * enc_output = Base64Encode(enc_input.c_str(), enc_input.length(),
with_new_line);
24. cout << \ << endl << \ << enc_output << \ << endl <<
endl; 25.
26. string dec_input = enc_output;
27. char * dec_output = Base64Decode((char *)dec_input.c_str(), dec_input.le
ngth(), with_new_line);
28. cout << \ << endl << \ << dec_output << \ << endl <<
endl; 29.
30. free(enc_output); 31. free(dec_output); 32. } 33.
34. char * Base64Encode(const char * input, int length, bool with_new_line) 35. {
36. BIO * bmem = NULL; 37. BIO * b64 = NULL; 38. BUF_MEM * bptr = NULL; 39.
40. b64 = BIO_new(BIO_f_base64()); 41. if(!with_new_line) {
42. BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 43. }
44. bmem = BIO_new(BIO_s_mem()); 45. b64 = BIO_push(b64, bmem); 46. BIO_write(b64, input, length); 47. BIO_flush(b64);
48. BIO_get_mem_ptr(b64, &bptr); 49.
50. char * buff = (char *)malloc(bptr->length + 1); 51. memcpy(buff, bptr->data, bptr->length); 52. buff[bptr->length] = 0; 53.
54. BIO_free_all(b64); 55.
56. return buff; 57. } 58.
59. char * Base64Decode(char * input, int length, bool with_new_line) 60. {
61. BIO * b64 = NULL; 62. BIO * bmem = NULL;
63. char * buffer = (char *)malloc(length); 64. memset(buffer, 0, length); 65.
66. b64 = BIO_new(BIO_f_base64()); 67. if(!with_new_line) {
68. BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 69. }
70. bmem = BIO_new_mem_buf(input, length);
71. bmem = BIO_push(b64, bmem); 72. BIO_read(bmem, buffer, length); 73.
74. BIO_free_all(bmem); 75.
76. return buffer; 77. }
Makefile
[plain] view plaincopy
1. INC_OPT = -I/usr/include/openssl 2. LNK_OPT = -g -L/usr/lib64/ -lssl 3. 4. all:
5. g++ main.cpp -g -o test $(INC_OPT) $(LNK_OPT)
执行结果1(编码结果每64个字符换行一次)
[plain] view plaincopy
1. [root@ampcommons02 base64-test]# ./test 2. With new line? y/n y 3.
4. To be encoded:
5. ~Henry Alfred Kissinger is a German-born American writer, political scientis
t, diplomat, and businessman. A recipient of the Nobel Peace Prize, he served as National Security Advisor and later concurrently as Secretary of State in the administrations of Presidents Richard Nixon and Gerald Ford.~ 6.
7. Base64 Encoded:
8. ~SGVucnkgQWxmcmVkIEtpc3NpbmdlciBpcyBhIEdlcm1hbi1ib3JuIEFtZXJpY2Fu 9. IHdyaXRlciwgcG9saXRpY2FsIHNjaWVudGlzdCwgZGlwbG9tYXQsIGFuZCBidXNp 10. bmVzc21hbi4gQSByZWNpcGllbnQgb2YgdGhlIE5vYmVsIFBlYWNlIFByaXplLCBo 11. ZSBzZXJ2ZWQgYXMgTmF0aW9uYWwgU2VjdXJpdHkgQWR2aXNvciBhbmQgbGF0ZXIg 12. Y29uY3VycmVudGx5IGFzIFNlY3JldGFyeSBvZiBTdGF0ZSBpbiB0aGUgYWRtaW5p 13. c3RyYXRpb25zIG9mIFByZXNpZGVudHMgUmljaGFyZCBOaXhvbiBhbmQgR2VyYWxk 14. IEZvcmQu 15. ~ 16.
17. Base64 Decoded:
18. ~Henry Alfred Kissinger is a German-born American writer, political scientis
t, diplomat, and businessman. A recipient of the Nobel Peace Prize, he served as National Security Advisor and later concurrently as Secretary of State in the administrations of Presidents Richard Nixon and Gerald Ford.~
执行结果2(编码结果不换行)
[plain] view plaincopy
1. [root@ampcommons02 base64-test]# ./test 2. With new line? y/n n 3.
4. To be encoded:
5. ~Henry Alfred Kissinger is a German-born American writer, political scientis
t, diplomat, and businessman. A recipient of the Nobel Peace Prize, he served as National Security Advisor and later concurrently as Secretary of State in the administrations of Presidents Richard Nixon and Gerald Ford.~ 6.
7. Base64 Encoded:
8. ~SGVucnkgQWxmcmVkIEtpc3NpbmdlciBpcyBhIEdlcm1hbi1ib3JuIEFtZXJpY2FuIHdyaXRlciw
gcG9saXRpY2FsIHNjaWVudGlzdCwgZGlwbG9tYXQsIGFuZCBidXNpbmVzc21hbi4gQSByZWNpcGllbnQgb2YgdGhlIE5vYmVsIFBlYWNlIFByaXplLCBoZSBzZXJ2ZWQgYXMgTmF0aW9uYWwgU2VjdXJpdHkgQWR2aXNvciBhbmQgbGF0ZXIgY29uY3VycmVudGx5IGFzIFNlY3JldGFyeSBvZiBTdGF0ZSBpbiB0aGUgYWRtaW5pc3RyYXRpb25zIG9mIFByZXNpZGVudHMgUmljaGFyZCBOaXhvbiBhbmQgR2VyYWxkIEZvcmQu~ 9.
10. Base64 Decoded:
11. ~Henry Alfred Kissinger is a German-born American writer, political scientis
t, diplomat, and businessman. A recipient of the Nobel Peace Prize, he served as National Security Advisor and later concurrently as Secretary of State in the administrations of Presidents Richard Nixon and Gerald Ford.~
注意
1)参考1的原文中,Encode示例代码中有一处错误:base64(\sizeof(\应该是 base64(\strlen(\
2)参考1的原文中,编码结果中,每64个字符换行一次,整个编码后的字符串的末尾也有换行。这是因为没有做BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL) 操作 3)参考1的原文中,下面红色标记的地方的用法有误!事实上,都要加1!否则,解码还原出来的字符串与编码前的原始字符串相比,丢失两个字符!
char *base64(const unsigned char *input, int length) {
BIO *bmem, *b64; BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64()); bmem = BIO_new(BIO_s_mem()); b64 = BIO_push(b64, bmem); BIO_write(b64, input, length); BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char *)malloc(bptr->length); memcpy(buff, bptr->data, bptr->length-1); buff[bptr->length-1] = 0;
BIO_free_all(b64);
return buff; }
4)上面的实例代码中,Base64Encode() 函数和 Base64Decode() 函数的返回值的buffer 是在Base64Encode() 函数和 Base64Decode() 里面申请的,因此,调用者在使用完这些buffer以后,自己free这些buffer(30、31行)
5)上面的示例代码中,41-43行、67-69行对“编码结果是否有换行”做了区分。这样做是为了方便兼容不带换行的base64编码方式,比如Java的程序用不带换行的base64方式编码的结果,C++也要能解码;或者Java程序只对不带换行的字符串做解码,那么C++代码也要能用不带换行的方式做base64编码。(Java SDK的base64编解码默认是采取不带换行的方式,如果设置了“chunk”属性,可以支持带换行的方式)。注意,这里的换行指的是一个'\\n'
6)用openssl 命令行做base64编解码是这样的:
[plain] view plaincopy
1. [root@ampcommons02 base64-test]# echo -n \
-born American writer, political scientist, diplomat, and businessman.\enssl enc -base64
2. SGVucnkgQWxmcmVkIEtpc3NpbmdlciBpcyBhIEdlcm1hbi1ib3JuIEFtZXJpY2Fu 3. IHdyaXRlciwgcG9saXRpY2FsIHNjaWVudGlzdCwgZGlwbG9tYXQsIGFuZCBidXNp 4. bmVzc21hbi4=
5. [root@ampcommons02 base64-test]# echo \
Edlcm1hbi1ib3JuIEFtZXJpY2Fu
6. > IHdyaXRlciwgcG9saXRpY2FsIHNjaWVudGlzdCwgZGlwbG9tYXQsIGFuZCBidXNp 7. > bmVzc21hbi4=
8. > \
9. Henry Alfred Kissinger is a German-born American writer, political scientist
, diplomat, and businessman.[root@ampcommons02 base64-test]#
由上可见,用openssl命令行做base64编码的结果是每64个字符换行一次,整个编码后的字符串的末尾也有换行;同样,用openssl命令行做base64解码的时候,输入的带解码字符串也必须是“每64个字符换行一次,整个编码后的字符串的末尾也有换行”的。