int mbedtls_base64_decode(
unsigned char *dst,
size_t dlen,
size_t *olen,
const unsigned char *src,
size_t slen
)
base64
解码
unsigned char *dst
是解码后的数据存放的地方。C语言中没有其他语言中的byte
类型,C语言中表达byte
类型就是用unsigned char
,unsigned char
的意思就是告诉编译器, 不要把我的最高位当成符号位,这样这8bit
就都表示真实的数据了。
size_t
的定义:
typedef long unsigned int __darwin_size_t;
typedef __darwin_size_t size_t;
size_t dlen
是unsigned char *dst
的大小,单位是字节
。
size_t *olen
是一个指针,用来存放unsigned char *dst
中最终写入了多少字节
数据。 为啥要传入指针呢?这是因为这个数字会变化,在函数内部对其指向的内容做了修改。
const unsigned char *src
表示要解码的字节数据
,我们知道,base64
编码的内容是ASCII字符集中的字符组成的字符串, 定义为const char *src
更为精确。但是这里定义成了const unsigned char *src
, 这就没有明确说这个里面存放的是ASCII字符集中的字符组成的字符串。 但是我们自己是知道的,这里面存放的就是ASCII字符集中的字符组成的字符串。 而由ASCII字符集中的字符组成的字符串使用const unsigned char *src
和const char *src
是一样的,可以进行相互转换。但是,如果不是ASCII字符集中的字符组成的字符串使用const unsigned char *src
和const char *src
是不一样的,需要注意这一点。
size_t slen
是const unsigned char *src
的大小,单位是字节
。
注意:
size_t dlen
到底应该传入多少呢?这有2
个办法得知:
方法一:如果你熟悉base64
解码,自己就可以估算出来,如下:
size_t outputLength = (inputLength >> 2) * 3;
方法二:如果你不熟悉base64
解码,就调用本函数,只要dst = NULL; dlen = 0
,所需要的长度就保存在size_t *olen
中了,如下:
mbedtls_base64_decode(NULL, 0, writenBytes, input, inputLength);
0
表示解码成功。
MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL
表示因为传入的dlen
不够大, 解码后的数据根本无法全部放在dst
中。
MBEDTLS_ERR_BASE64_INVALID_CHARACTER
表示因为传入的src
中含有不属于base64
编码中的字符, 或者src
不是base64
编码。
step1、创建一个项目目录base64
并进入该目录
mkdir base64 && cd base64
step2、使用curl命令下载base64.h
和base64.c
两个文件:
curl -LO https://raw.githubusercontent.com/ARMmbed/mbedtls/master/include/mbedtls/base64.h
curl -LO https://raw.githubusercontent.com/ARMmbed/mbedtls/master/library/base64.c
step3、创建config.h
文件,其内容如下
#define MBEDTLS_BASE64_C
MBEDTLS_BASE64_C
这个宏控制着是否开启BASE64
相关的定义。
step4、将base64.c
中的mbedtls/
字符串去掉
sed -i 's@mbedtls/@@g' base64.c 2> /dev/null ||
sed -i "" 's@mbedtls/@@g' base64.c
step5、编写一个C语言源程序base64Test.c
,其内容如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "base64.h"
void showHelp() {
printf("usage: base64 decode xxxx\n");
exit(1);
}
unsigned char* base64Decode(char* input, size_t* writenBytes, int* resultCode) {
size_t inputLength = strlen(input);
//base64编码的字符串的长度必须是4的整数倍
if (inputLength & 3 != 0) {
(*resultCode) = MBEDTLS_ERR_BASE64_INVALID_CHARACTER;
return NULL;
}
size_t outputLength = (inputLength >> 2) * 3;
//解码后的数据
unsigned char* output = (unsigned char*) calloc(outputLength, sizeof(char));
//解码
(*resultCode) = mbedtls_base64_decode(output, outputLength, writenBytes, (unsigned char*)input, inputLength);
0 == (*resultCode) ? return output : return NULL;
}
int main(int argc, char* argv[]) {
if (argc == 3) {
if (strcmp("decode", argv[1]) == 0) {
size_t writenBytes = 0;
int resultCode = -1;
unsigned char* output = base64Decode(argv[2], &writenBytes, &errorCode);
if (NULL == output) {
printf("error occurred. code is %d\n", resultCode);
return resultCode;
} else {
printf("base64(%s) = %s\n", output, argv[2]);
}
} else {
showHelp();
}
} else {
showHelp();
}
return 0;
}
step6、使用cc命令进行编译:
cc -o base64Test base64Test.c base64.c
step7、执行base64Test
,结果如下
./base64Test decode YWJj
base64(abc) = YWJj
step8、在在线工具中输入相同的字符,看看输出是否一样。
source code on GitHub