您的位置:首页 > 其它

关于Base64编码(转载)

2005-09-08 21:15 676 查看
关于Base64编码(转载) feijunjun(军仔) 2002-05-02 15:16:52发表.把一三个字符的24位码转换成四个高两位为0的ASCII码,其实也就是四个字母[取自于码表: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/]如 10101101 10111010 01110110 ----------------- -------- 这里是一个中文字[8位高一位不为0] 这是一个英文字母[高一位为0]可以转成00101011 00011011 00101001 00110110 ------ ------ ------ ------ =>这里正好是上面的 那27位值 2B 1B 2A 36 以下是 10 进制码表中的索引 43 27 42 54对应码表中的值 r b q 2 所以上面的24位编码,编码后值为 rbq2 解码同理把rbq2的二进制位连接上再重组得到三个 8位值,得出原码很明白了吧,呵呵 ====================================================================soundbug(兼职乞丐) 2002-03-22 09:42:53发表我收藏的一篇文章:-------------------------------------------------------------------一般大多数包含"="的不是"Base64"编码格式,只有"quoted-printable"编码格式才会经常出现"="虽然都是MIME编码,但是算法不一样,"quoted-printable"的我不太清楚.讲一下Base64的吧. Base64算法是把3个8位字符(24)转换成4个6位字符(32),因此编码后的长度会扩大1/3,进行编码转换时需要用到一张Base64的编码表: Table 1: The Base64 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y在VB中可以简单的将其保存为一个常量:Private Const Base64Table ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" 编码过程是这样的,第一个字符通过右移2位获得第一个目标字符的Base64表位置,根据这个数值取到表上相应的字符,就是第一个目标字符,然后将第一个字符左移6位加上第二个字符右移4位,即获得第二个目标字符,再将第二个字符左移4位加上第三个字符右移6位,获得第三个目标字符,最后取第三个字符的右6位即获得第四个目标字符. 例如我们取一个简单的字符串"TEST..."将其用SourceByte = StrConv(SourceText, vbFromUnicode)转换后获得二进制数组:T E S T ...84 69 83 84 ...01010100 01000101 01010011 01010100 ...01010100/01000101/01010011/0101010001010100010001010101001101010100转换后:01010100010001010101001101010100010101/000100/010101/010011/010101/00010101 000100 010101 010011 010101 00....21 4 21 19 21 ...V E V T V ...最后得到的就是"VEVTV..." 对于第一个目标字符我们可以这样做:(SourceByte(1) and 252)/4第二个:(SourceByte(1) and 3)*64 + (SourceByte(2) and 240)/16第三个:(SourceByte(2) and 15)*16 + (SourceByte(3) and 48)/64第四个:(SourceByte(3) and 63) Base64解码过程正好相反,我就不多说了,另外有关MIME的RFC还是有很多的,如果需要详细情况请自己查找,我上面那张表就摘自<RFC1521#MIME (Multipurpose Internet Mail Extensions)Part One: Mechanisms for Specifying and Describing the Format of InternetMessage Bodies> ====================================================================xuying() 2002-08-21 12:10:55发表MIME/BASE64 的算法很简单,它将字符流顺序放入一个 24 位的缓冲区,缺字符的地方补零。然后将缓冲区截断成为 4 个部分,高位在先,每个部分 6 位,用下面的 64 个字符重新表示:“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop qrstuvwxyz0123456789+/”。如果输入只有一个或两个字节,那么输出将用等号“=”补足。这可以隔断附加的信息造成编码的混乱。这就是BASE64。 UEsDBBQAAgAIAEapPiS/mrkHoQEAAEECAAAMAAAAYWNhZDd+dWUudHh0dVFRb5swGHyPlP9Q5IetTUICzCUJASTiFuIQhwbHRJnUqmRsndqmVQO0CsK/fXbRVvVh+AV9vrvv7txunYiPV8rAW3n33w5BR9FAN3ld34Axr9OHIjtkt7wC3bmKHD+zznjteTGvjBnVFGCdxz265XW7dfI+ZVFyRjegO3hix8nlfGcdjeLqy/rGTp0Sj+Jp8Djho9oIWRSX0IYIwwmWbF4RHKYK0ByCaI9u4u3HukYZIvE32+fZyz7L BASE64编码转换原理 Base64编码其实是将3个8位字节转换为4个6位字节,( 3*8 = 4*6 = 24 ) 这4个六位字节 其实仍然是8位,只不过高两位被设置为0. 当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0~63) 。 事实上,0~63之间的ASCII码有许多不可见字符,所以应该再做一个映射,映射表为 ‘A‘ ~ ‘Z‘ ? ASCII(0 ~ 25) ‘a’ ~ ‘z‘ ? ASCII(26 ~ 51) ‘0’ ~ ‘9‘ ? ASCII(52 ~ 61) ‘+‘ ? ASCII(62) ‘/‘ ? ASCII(63) 这样就可以将3个8位字节,转换为4个可见字符。 具体的字节拆分方法为:(图(画得不好,领会精神 :-)) aaaaaabb ccccdddd eeffffff ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ 字节 1 字节 2 字节 3 || // 00aaaaaa 00bbcccc 00ddddee 00ffffff 注:上面的三个字节位原文,下面四个字节为Base64编码,其前两位均为0。 这样拆分的时候,原文的字节数量应该是3的倍数,当这个条件不能满足时,用全零字节 补足,转化时Base64编码用=号代替,这就是为什么有些Base64编码以一个或两个等号结 束的原因,但等号最多有两个,因为:如果F(origin)代表原文的字节数,F(remain)代 表余数,则 F(remain) = F(origin) MOD 3 成立。 所以F(remain)的可能取值为0,1,2. 如果设 n = [F(origin) – F(remain)] / 3 当F(remain) = 0 时,恰好转换为4*n个字节的Base64编码。 当F(remain) = 1 时,由于一个原文字节可以拆分为属于两个Base64编码的字节,为了 让Base64编码是4的倍数,所以应该为补2个等号。 当F(remain) = 2 时,由于两个原文字节可以拆分为属于3个Base64编码的字节,同理, 应该补上一个等号。 ====================================================================duz() 2001-04-14 01:05:00 发表#include <windows.h> #define BaseCode64Size(nInputSize) ((nInputSize+2)/3*4)#define DeBaseCod64Size(nInputSize) ((nInputSize/4)*3)BOOL DecodeBase64(const char *pszIn, BYTE *pszOut, int *nOutLen);BOOL EncodeBase64(const BYTE* pszIn, int nInLen, char* pszOut);int CodeFromChar(char x); const char m_base64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz0123456789+/"; int CodeFromChar(char x){ if('A'<=x&&x<='Z') return x-'A'; if('a'<=x&&x<='z') return x-'a'+26; if('0'<=x&&x<='9') return x-'0'+52; if(x=='+') return 62; if(x=='/') return 63; if(x=='='||x=='/r'||x=='/n') return 64; return -1;} int sizeofstr(const char *str){ int i=0; while(str[i++]); return i-1;} BOOL DecodeBase64(const char *pszIn, BYTE *pszOut, int *nOutLen){ if(IsBadStringPtr(pszIn,0xFFFFFFFF)) return FALSE; int len=sizeofstr(pszIn); int OutSize=DeBaseCod64Size(len); if(IsBadWritePtr(pszOut,OutSize)) return FALSE; int nInPos=0; int nOutPos=0; for(int i=0;pszIn[nInPos]!='/0';i++) { int c1,c2,c3,c4; if((c1=CodeFromChar(pszIn[nInPos++]))==-1) return FALSE; if(c1==64) continue; if((c2=CodeFromChar(pszIn[nInPos++]))==-1) return FALSE; if(c2==64) return FALSE; if((c3=CodeFromChar(pszIn[nInPos++]))==-1) return FALSE; if(c3==64) return FALSE; if((c4=CodeFromChar(pszIn[nInPos++]))==-1) return FALSE; if(c4==64) return FALSE; if(c1==-1||c2==-1||c3==-1||c4==-1) { return FALSE; } if(c1==64||c2==64||c3==64||c4==64) { nInPos-=3; return FALSE; } pszOut[nOutPos++]=(BYTE)((c1<<2)|(c2>>4)); pszOut[nOutPos++]=(BYTE)((c2<<4)|(c3>>2)); pszOut[nOutPos++]=(BYTE)((c3<<6)|(c4)); } *nOutLen=nOutPos; return TRUE;} BOOL EncodeBase64(const BYTE* pszIn, int nInLen, char* pszOut){ int nOutLen; if(IsBadReadPtr(pszIn,nInLen)) return FALSE; nOutLen=BaseCode64Size(nInLen)+1; if(IsBadWritePtr(pszOut,nOutLen)) return FALSE; int nInPos=0; int nOutPos=0; for (int i=0; i<nInLen/3; ++i) { //Get the next 2 characters int c1 = (int)pszIn[nInPos++]; int c2 = (int)pszIn[nInPos++]; int c3 = (int)pszIn[nInPos++]; //Encode into the 4 6 bit characters pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; pszOut[nOutPos++] = m_base64tab[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]; pszOut[nOutPos++] = m_base64tab[c3 & 0x3F]; } switch (nInLen % 3) { case 0: { pszOut[nOutPos++]='/0'; break; } case 1: { int c1 = pszIn[nInPos]; pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4)]; pszOut[nOutPos++] = '='; pszOut[nOutPos++] = '='; pszOut[nOutPos++] = '/0'; break; } case 2: { int c1 = pszIn[nInPos++] ; int c2 = pszIn[nInPos] ; pszOut[nOutPos++] = m_base64tab[(c1 & 0xFC) >> 2]; pszOut[nOutPos++] = m_base64tab[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; pszOut[nOutPos++] = m_base64tab[((c2 & 0x0F) << 2)]; pszOut[nOutPos++] = '='; pszOut[nOutPos++] = '/0'; break; } default: { //This is impossible, so release memory is not needed return FALSE; } } return TRUE;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: