Base64编码及代码

BASE64编码是一种常用的将十六进制数据转换为可见字符的编码。与ASCII码相比,它占用的空间较小。BASE64编码在rfc3548中定义。

  

1、base64编解码原理

      关于这个编码的规则:

    1)把3个字符变成4个字符

  2)每76个字符加一个换行符

  3)最后的结束符也要处理

       

  将数据编码成BASE64编码时,3字符转4字符后,每个字符6bit,得到一个数字:0-63。但是由于0-63中有很多不可打印字符,需要进行二次映射,映射的规则就是

      0~25:A~Z

      26~51:a~z

      52~61:0~9

      62:+

      63:/

 

  比如有数据:0x30 0x82 0x02

  编码过程如下:

  1)得到16进制数据: 30 82 02

  2)得到二进制数据: 00110000 10000010 00000010

  3)每6bit分组: 001100 001000 001000 000010

  4)得到数字: 12 8 8 2

  5)根据查表得到结果 : M I I C

  

      BASE64填充:在不够的情况下在右边加0。

  有三种情况:

  1) 输入数据比特数是24的整数倍(输入字节为3字节整数倍),则无填充;

  2) 输入数据最后编码的是1个字节(输入数据字节数除3余1),即8比特,则需要填充2个"==",因为要补齐6比特,需要加2个00;

  3)输入数据最后编码是2个字节(输入数据字节数除3余2),则需要填充1个"=",因为补齐6比特,需要加一个00。

  举例如下:

  对0x30编码:

  1) 0x30的二进制为:00110000

  2) 分组为:001100 00

  3) 填充2个00:001100 000000

  4) 得到数字:12 0

  5) 查表得到的编码为MA,另外加上两个==

  所以最终编码为:MA==

 

2、Base64编解码,下面代码参考开源软件cyassl:

#include <stdio.h> #include <stdlib.h> #include <string.h> enum { BAD = 0xFF, /* invalid encoding */ PAD = '=', PEM_LINE_SZ = 64 }; static const char base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, BAD, BAD, BAD, BAD, BAD, BAD, BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, BAD, BAD, BAD, BAD, BAD, BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; int Base64Decode(const char* in, int inLen, char * out, int * outLen) { int i = 0; int j = 0; while (inLen > 3) { char b1, b2, b3; char e1 = in[j++]; char e2 = in[j++]; char e3 = in[j++]; char e4 = in[j++]; int pad3 = 0; int pad4 = 0; if (e1 == 0) /* end file 0's */ break; if (e3 == PAD) pad3 = 1; if (e4 == PAD) pad4 = 1; e1 = base64Decode[e1 - 0x2B]; e2 = base64Decode[e2 - 0x2B]; e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; b1 = (e1 << 2) | (e2 >> 4); b2 = ((e2 & 0xF) << 4) | (e3 >> 2); b3 = ((e3 & 0x3) << 6) | e4; out[i++] = b1; if (!pad3) out[i++] = b2; if (!pad4) out[i++] = b3; else break; inLen -= 4; if (in[j] == ' ' || in[j] == '/r' || in[j] == '/n') { char endLine = in[j++]; inLen--; while (endLine == ' ') { /* allow trailing whitespace */ endLine = in[j++]; inLen--; } if (endLine == '/r') { endLine = in[j++]; inLen--; } if (endLine != '/n') return -1; } } *outLen = i; return 0; } static const char base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; int Base64Encode(const char* in, int inLen, char * out, int* outLen) { int i = 0,j = 0,n = 0; /* new line counter */ int outSz = (inLen + 3 - 1) / 3 * 4; if (outSz > *outLen) return -1; while (inLen > 2) { char b1 = in[j++]; char b2 = in[j++]; char b3 = in[j++]; /* encoded idx */ char e1 = b1 >> 2; char e2 = ((b1 & 0x3) << 4) | (b2 >> 4); char e3 = ((b2 & 0xF) << 2) | (b3 >> 6); char e4 = b3 & 0x3F; /* store */ out[i++] = base64Encode[e1]; out[i++] = base64Encode[e2]; out[i++] = base64Encode[e3]; out[i++] = base64Encode[e4]; inLen -= 3; if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) out[i++] = '/n'; } /* last integral */ if (inLen) { int twoBytes = (inLen == 2); char b1 = in[j++]; char b2 = (twoBytes) ? in[j++] : 0; char e1 = b1 >> 2; char e2 = ((b1 & 0x3) << 4) | (b2 >> 4); char e3 = (b2 & 0xF) << 2; out[i++] = base64Encode[e1]; out[i++] = base64Encode[e2]; out[i++] = (twoBytes) ? base64Encode[e3] : PAD; out[i++] = PAD; } //out[i++] = '/n'; if (i != outSz) return -1; *outLen = outSz; return 0; } int main() { char * sstr = "123Hello987World+=%456"; char encrystr[256]; int len = 256; memset(encrystr,'/0',256); Base64Encode(sstr,strlen(sstr),encrystr, &len); printf("estr : %s/n",encrystr); char decrystr[256]; memset(decrystr,'/0',256); Base64Decode(encrystr,len,decrystr,&len); printf("dstr : %s/n",decrystr); return 0; }

你可能感兴趣的:(c,File,encoding,whitespace)