user-0 提问: base64解码的长度怎么算?

回复:
user: user-1

user: user-2
content: 引用 5 楼 qq_40162781 的回复:[quote=引用 3 楼 舉杯邀明月 的回复:]假设编码之后的字符数是Ｌ，那么解码长度： n = L/4*3 +(3&(L-1))%3  不管BASE64文本的后面是否补了＝，上面的计算结果肯定是“原始长度”n。   为什么是+， 还有(3&(L-1))%3是什么意思。。  [/quote] 刚才把我以前写的BASE64模块找来看了一下，发现我在3楼的说法不太准确。   Ｌ的值 是BASE64编码文本去掉分隔符（按“标准”要76字符换行）、 　去掉末尾的=字符之后的“纯编码”长度值。 昨天回复时，忘记我的“中间处理层”接口函数了。

user: user-2
content: 引用 5 楼 qq_40162781 的回复:[quote=引用 3 楼 舉杯邀明月 的回复:]假设编码之后的字符数是Ｌ，那么解码长度： n = L/4*3 +(3&(L-1))%3  不管BASE64文本的后面是否补了＝，上面的计算结果肯定是“原始长度”n。   为什么是+， 还有(3&(L-1))%3是什么意思。。  [/quote]  你在C版块提问，不至于看不懂 C语言格式的运算表达式吧。

user: user-0
content: 引用 3 楼 舉杯邀明月 的回复:假设编码之后的字符数是Ｌ，那么解码长度： n = L/4*3 +(3&(L-1))%3  不管BASE64文本的后面是否补了＝，上面的计算结果肯定是“原始长度”n。   为什么是+， 还有(3&(L-1))%3是什么意思。。

user: user-2
content: 另外： 如果BASE64文本的编码长度为Ｌ 如果： 3 & L ==1 那么： 编码长度不合法！

user: user-2
content: 假设编码之后的字符数是Ｌ，那么解码长度： n = L/4*3 +(3&(L-1))%3  不管BASE64文本的后面是否补了＝，上面的计算结果肯定是“原始长度”n。

user: user-3
content: 太帅了啊

user: user-3
content: 好像字节对齐也是用这原理?

user: user-1
content: 仅供参考：#include <stdio.h> #include <string.h> #include <stdlib.h>  #define BASE64_VALUE_SZ 256 int     base64_value[BASE64_VALUE_SZ]; const unsigned char alphabet[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; class Base64Utility { public:     Base64Utility();     int base64_encode(char *src, int srclen, char *dst, int tail);     int base64_decode(char *src, int srclen, char *dst); private:     void base_64_init(void); }; Base64Utility::Base64Utility() {     base_64_init(); } void Base64Utility::base_64_init(void) {     int i;      for (i = 0; i < BASE64_VALUE_SZ; i++) base64_value[i] = -1;     for (i = 0; i < 64; i++) base64_value[(int) alphabet[i]] = i;     base64_value['='] = 0; } int Base64Utility::base64_encode(char *src, int srclen, char *dst, int tail) {     int     bits, char_count, len;     char    *o_char, *lim, *o_lim;     unsigned char   c;      if ( !src || !dst) return 0;     len = srclen;     lim = src + len;     o_char = dst;     o_lim  = dst + (len*4)/3 + 1;     char_count = 0;     bits = 0;     while ( (src < lim) && (o_char < o_lim)) {         c = *(src++);         bits += c;         char_count++;         if (char_count == 3) {             *(o_char++) = alphabet[bits >> 18];             *(o_char++) = alphabet[(bits >> 12) & 0x3f];             *(o_char++) = alphabet[(bits >> 6) & 0x3f];             *(o_char++) = alphabet[bits & 0x3f];             bits = 0;             char_count = 0;         } else {             bits <<= 8;         }     }     if (char_count != 0) {         bits <<= 16 - (8 * char_count);         *(o_char++) = alphabet[bits >> 18];         *(o_char++) = alphabet[(bits >> 12) & 0x3f];         if (char_count == 1) {             if (tail) {                 *(o_char++) = '=';                 *(o_char++) = '=';             }         } else {             *(o_char++) = alphabet[(bits >> 6) & 0x3f];             if (tail) {                 *(o_char++) = '=';             }         }     }     *(o_char) = 0;     return strlen(dst); } int Base64Utility::base64_decode(char *src, int srclen, char *dst) {     int j;     unsigned int k;     int c, base_result_sz;     long val;      if (!src || !dst) return 0;     base_result_sz = srclen;     val = c = 0;     for (j = 0; *src; src++) {         k = (int) *src % BASE64_VALUE_SZ;         if (base64_value[k] < 0) continue;         val <<= 6;         val += base64_value[k];         if (++c < 4) continue;         dst[j++] = (char) (val >> 16);         dst[j++] = (val >> 8) & 0xff;         dst[j++] = val & 0xff;         val = c = 0;     }     switch (c) {         case 2://xxxxxx xx0000             dst[j++] = (val >> 4) & 0xff;         break;         case 3://XXXXXX XXxxxx xxxx00             dst[j++] = (char) (val >> 10);             dst[j++] = (val >> 2) & 0xff;         break;     }     return j; } Base64Utility b64u; #define MAXLENS 1024768 #define MAXLEND 1366360 char bufd[MAXLEND]; char bufs[MAXLENS]; FILE *fs,*fd; int fsize; int main(int argc,char *argv[]) {     if (argc<4) {     USE:         printf("%s <-e|-E|-d> srcfile desfile\n",argv[0]);         return 1;     }     if (stricmp(argv[1],"-e") && stricmp(argv[1],"-d")) goto USE;     if (0==stricmp(argv[1],"-e")) {         fs=fopen(argv[2],"rb");         if (NULL==fs) {             printf("Can not open file %s!\n",argv[2]);             return 2;         }         fsize=fread(bufs,1,MAXLENS,fs);         if (fsize<=0) {             fclose(fs);             printf("Can not read file %s!\n",argv[2]);             return 3;         }         if (MAXLENS==fsize) printf("Warning: Up to %d bytes.\n",MAXLENS);         fclose(fs);         b64u.base64_encode(bufs,fsize,bufd,('E'==argv[2][1]));         fd=fopen(argv[3],"w");         if (NULL==fd) {             printf("Can not create file %s!\n",argv[3]);             return 4;         }         fprintf(fd,"%s",bufd);         fclose(fd);     } else {//0==stricmp(argv[1],"-d")         fd=fopen(argv[2],"rb");         if (NULL==fd) {             printf("Can not open file %s!\n",argv[2]);             return 2;         }         fsize=fread(bufd,1,MAXLEND,fd);         if (fsize<=0) {             fclose(fd);             printf("Can not read file %s!\n",argv[2]);             return 3;         }         if (MAXLEND==fsize) printf("Warning: Up to %d bytes.\n",MAXLEND);         fclose(fd);         fsize=b64u.base64_decode(bufd,fsize,bufs);         fs=fopen(argv[3],"wb");         if (NULL==fs) {             printf("Can not create file %s!\n",argv[3]);             return 4;         }         if (fsize!=(int)fwrite(bufs,1,fsize,fs)) {             printf("Write %s error!\n",argv[3]);             fclose(fs);             return 5;         }         fclose(fs);     }     return 0; }

user: user-4
content: 因为base64存在补=号，所以算出来的只是一个范围，长度*3/4+1最大长度，如果要具体算出来编码之前的长度，需要自行判断补=号情况减去对应的占位