最近,有项目中需要用到base64的加解密,所以用C语言实现了一遍,测试效果还不错,代码量和RAM消耗都比较低,可以提供给大家参考下。
#include #include #include "base64.h" static uint8_t get_index_from_char(char c) { if ((c >= 'A') && (c <= 'Z')) return (c - 'A'); else if ((c >= 'a') && (c <= 'z')) return (c - 'a' + 26); else if ((c >= '0') && (c <= '9')) return (c - '0' + 52); else if (c == '+') return 62; else if (c == '/') return 63; else if (c == '=') return 64; else if ((c == 'r') || (c == 'n')) return 254; else return 255; } static char get_char_from_index(uint8_t i) { if ((i >= 0) && (i <= 25)) return (i + 'A'); else if ((i >= 26) && (i <= 51)) return (i - 26 + 'a'); else if ((i >= 52) && (i <= 61)) return (i - 52 + '0'); else if (i == 62) return '+'; else if (i == 63) return '/'; else return '='; } int base64_encode(const uint8_t *in, uint16_t in_len, char *out) { int i; uint32_t tmp = 0; uint16_t out_len = 0; uint16_t left = in_len; if ((!in) || (!out)) { //invalid parameter return BASE64_ERROR; } for (i = 0; i < in_len;) { if (left >= 3) { tmp = in[i]; tmp = (tmp << 8) + in[i+1]; tmp = (tmp << 8) + in[i+2]; out[out_len++] = get_char_from_index((tmp & 0x00FC0000) >> 18); out[out_len++] = get_char_from_index((tmp & 0x0003F000) >> 12); out[out_len++] = get_char_from_index((tmp & 0x00000FC0) >> 6); out[out_len++] = get_char_from_index(tmp & 0x0000003F); left -= 3; i += 3; } else { break; } } if (left == 2) { tmp = in[i]; tmp = (tmp << 8) + in[i+1]; out[out_len++] = get_char_from_index((tmp & 0x0000FC00) >> 10); out[out_len++] = get_char_from_index((tmp & 0x000003F0) >> 4); out[out_len++] = get_char_from_index((tmp & 0x0000000F) << 2); out[out_len++] = get_char_from_index(64); } else if (left == 1) { tmp = in[i]; out[out_len++] = get_char_from_index((tmp & 0x000000FC) >> 2); out[out_len++] = get_char_from_index((tmp & 0x00000003) << 4); out[out_len++] = get_char_from_index(64); out[out_len++] = get_char_from_index(64); } out[out_len] = ''; return BASE64_SUCCESS; } int base64_decode(const char *in, uint8_t *out, uint16_t *out_len) { uint16_t i = 0, cnt = 0; uint8_t c, in_data_cnt; bool error_msg = false; uint32_t tmp = 0; if ((!in) || (!out) || (!out_len)) { //invalid parameter return BASE64_ERROR; } in_data_cnt = 0; while (in[i] != '') { c = get_index_from_char(in[i++]); if (c == 255) { //MSG_PRINTF(LOG_ERR, "INVALID MESSAGE CODEn"); return BASE64_ERR_BASE64_BAD_MSG; } else if (c == 254) { continue; // Carriage return or newline feed, skip } else if (c == 64) { break; // Meet '=', break } tmp = (tmp << 6) | c; if (++in_data_cnt == 4) { out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF); out[cnt++] = (uint8_t)((tmp >> 8) & 0xFF); out[cnt++] = (uint8_t)(tmp & 0xFF); in_data_cnt = 0; tmp = 0; } } // Meet '=' or '' if (in_data_cnt == 3) { // 3 chars before '=', encoded msg like xxx= OR tmp = (tmp << 6); // 3 chars before '', encoded msg like xxx, considered '=' omitted out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF); out[cnt++] = (uint8_t)((tmp >> 8) & 0xFF); } else if (in_data_cnt == 2) { // 2 chars before '=', encoded msg like xx== OR tmp = (tmp << 6); // 2 chars before '', encoded msg like xx, considered '=' omitted tmp = (tmp << 6); out[cnt++] = (uint8_t)((tmp >> 16) & 0xFF); } else if (in_data_cnt != 0) { error_msg = true; // Warn that the message format is wrong, but we tried our best to decode } *out_len = cnt; return (error_msg ? BASE64_ERROR : BASE64_SUCCESS); }
简单写了一个测试demo,有兴趣的可以一起看下。
#include #include #include "base64.h" #include "convert.h" int log_hexdump(const char *title, const unsigned char *data, int len) { char str[160], octet[10]; int ofs, i, k, d; const unsigned char *buf = (const unsigned char *)data; const char dimm[] = "+------------------------------------------------------------------------------+"; printf("%s (%d bytes):rn", title, len); printf("%srn", dimm); printf("| Offset : 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 0123456789ABCDEF |rn"); printf("%srn", dimm); for (ofs = 0; ofs < (int)len; ofs += 16) { d = snprintf( str, sizeof(str), "| %08X: ", ofs ); for (i = 0; i < 16; i++) { if ((i + ofs) < (int)len) { snprintf( octet, sizeof(octet), "%02X ", buf[ofs + i] ); } else { snprintf( octet, sizeof(octet), " " ); } d += snprintf( &str[d], sizeof(str) - d, "%s", octet ); } d += snprintf( &str[d], sizeof(str) - d, " " ); k = d; for (i = 0; i < 16; i++) { if ((i + ofs) < (int)len) { str[k++] = (0x20 <= (buf[ofs + i]) && (buf[ofs + i]) <= 0x7E) ? buf[ofs + i] : '.'; } else { str[k++] = ' '; } } str[k] = ''; printf("%s |rn", str); } printf("%srn", dimm); return 0; } int main(int argc, const char *argv[]) { const char *data = "C1D0F8FB4958670DBA40AB1F3752EF0D"; char base64_enc_calc[128] = {0}; char base64_enc_exp[128] = "QzFEMEY4RkI0OTU4NjcwREJBNDBBQjFGMzc1MkVGMEQ="; const char *p_calc = data; uint8_t base64_dec_calc[128]; uint16_t base64_dec_len = 0; int ret; if (argc > 1) { p_calc = argv[1]; } ret = base64_encode((const uint8_t *)p_calc, strlen(p_calc), base64_enc_calc); if (!ret && !strcmp(base64_enc_calc, base64_enc_exp)) { printf("base64_enc_calc: %sn", base64_enc_calc); printf("BASE64 encryption test OKn"); } else { printf("base64_enc_calc: %sn", base64_enc_calc); printf("base64_enc_exp : %sn", base64_enc_exp); printf("BASE64 encryption test FAILn"); } ret = base64_decode(base64_enc_calc, base64_dec_calc, &base64_dec_len); printf("ret: %dn", ret); if (!ret && !strcmp((char *)base64_dec_calc, p_calc)) { printf("base64_dec_calc: %sn", base64_dec_calc); printf("BASE64 decryption test OKn"); } else { printf("base64_dec_calc: %sn", base64_dec_calc); printf("base64_org_data: %sn", p_calc); printf("BASE64 decryption test FAILn"); } return 0; }
测试结果,还挺正常的。
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$ ./build.sh
gcc base64.c test.c ../../utils/convert.c -I../../utils -Wall -Werror -o test
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$
recan@ubuntu:~/win_share_workspace/coding-01workstation/workspace/crypto/base64$ ./test
base64_enc_calc: QzFEMEY4RkI0OTU4NjcwREJBNDBBQjFGMzc1MkVGMEQ=
BASE64 encryption test OK
ret: 0
base64_dec_calc: C1D0F8FB4958670DBA40AB1F3752EF0D
BASE64 decryption test OK
审核编辑:刘清
-
RAM
+关注
关注
8文章
1368浏览量
114630 -
C语言
+关注
关注
180文章
7604浏览量
136614 -
加解密
+关注
关注
0文章
18浏览量
6516
发布评论请先 登录
相关推荐
评论