Base64编码解码与实现
Base64是一種很常見的編碼規范,其定義為:Base64內容傳送編碼被設計用來把任意序列的8位字節描述為一種不易被人直接識別的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.),其作用是將二進制序列轉換為人類可讀的ASCII字符序列,常用在需用通過文本來傳輸二進制數據的協議中,如HTTP和SMTP等。
??? Base64編碼規則:對于待編碼數據,以3個字節為單位,依次取6位,前兩位補0形成8位編碼,由于3*8=4*6,3個字節的輸入會編碼成4個字節的輸出。如果剩下的字符不足3個字節,則用0填充,輸出字符使用'=',因此編碼后輸出的文本末尾可能會出現1或2個'='。
??? 為了保證所輸出的編碼位可讀字符,Base64制定了一個編碼表,以便進行統一轉換。編碼表的大小為2^6=64,這也是Base64名稱的由來。
?
?????????? Base64編碼表
???碼值?? 碼?? 碼值??碼??碼值碼??碼值? 碼
??????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
??????0???????? 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?
編碼詳解
1. 不加后補位的字符串“abC”
01100001?01100010 01000011
00011000 00010110 00001001 00000011
24?????? 22???????9????????3
查表可以得到編碼值為:“YWJD”。
?
2. 加后補位的字符串“ab”:
?
01100001?01100010
00011000 00010110 00001000 00000000
24?????? 22???????8????????-
?
由于不夠24個字節位,所以我們要加8個0字節位以湊夠24個?!?”表示增加的補位,編碼后應為“=”,所以可以得到編碼后的字符串為“YWI=”。
?
3. 加后補位的字符串“a”:
?
01100001
00011000 00010000 00000000 00000000
24???????16???????-????????-
?
同樣,編碼后的字符串為“YQ==”,只是這里出現了兩個“=”。
?
算法實現:
?
// Decode a block (4 bytes)
void decodeBlock(unsigned char *dest, char *src)
{
? unsigned int x = 0;
? int i;
? for(i = 0; i < 4; i++) {
??? if(src[i] >= 'A' && src[i] <= 'Z')
????? x = (x << 6) + (unsigned int)(src[i] - 'A' + 0);
??? else if(src[i] >= 'a' && src[i] <= 'z')
????? x = (x << 6) + (unsigned int)(src[i] - 'a' + 26);
??? else if(src[i] >= '0' && src[i] <= '9')
????? x = (x << 6) + (unsigned int)(src[i] - '0' + 52);
??? else if(src[i] == '+')
????? x = (x << 6) + 62;
??? else if(src[i] == '/')
????? x = (x << 6) + 63;
??? else if(src[i] == '=')
????? x = (x << 6);
? }
? dest[2] = (unsigned char)(x & 255); x >>= 8;
? dest[1] = (unsigned char)(x & 255); x >>= 8;
? dest[0] = (unsigned char)(x & 255); x >>= 8;
}
?
// decode the src string and store the decoded string to dest, return the
// length of decoded string in len
// NOTE: the length of dest buffer must be larger than (strlen(src)*3)/4+3
void base64Decode(unsigned char *dest, char *src, int *len)
{
? int length = 0;
? int equalsTerm = 0;
? int i;
? int numBlocks;
? unsigned char lastBlock[3];
? while((src[length] != '=') && src[length])
??? length++;
? while(src[length+equalsTerm] == '=')
??? equalsTerm++;
? numBlocks = (length + equalsTerm) / 4;
? if(len)
??? *len = (numBlocks * 3) - equalsTerm;
? for(i = 0; i < numBlocks - 1; i++) {
??? decodeBlock(dest, src);
??? dest += 3;
??? src += 4;
? }
? decodeBlock(lastBlock, src);
? for(i = 0; i < 3 - equalsTerm; i++)
??? dest[i] = lastBlock[i];
}
?
static char table64[]=
? "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
?
// encode the data from inbuf and store the encoded data into outbuf
// return the length of encoded data
// NOTE: do not forget to free the outbuf allocated here
int base64Encode(const void *inbuf, int inlen, char **outbuf)
{
? unsigned char ibuf[3];
? unsigned char obuf[4];
? int i;
? int inputparts;
? char *output;
? char *base64data;
? char *indata = (char *)inbuf;
? if(0 == inlen)
??? inlen = strlen(indata);
? base64data = output = (char*)malloc(inlen*4/3+4);
? if(NULL == output)
??? return -1;
? while(inlen > 0) {
??? for (i = inputparts = 0; i < 3; i++) {
????? if(inlen > 0) {
??????? inputparts++;
??????? ibuf[i] = *indata;
??????? indata++;
??????? inlen--;
????? }
????? else
??????? ibuf[i] = 0;
??? }
??? obuf [0] = (ibuf [0] & 0xFC) >> 2;
??? obuf [1] = ((ibuf [0] & 0x03) << 4) | ((ibuf [1] & 0xF0) >> 4);
??? obuf [2] = ((ibuf [1] & 0x0F) << 2) | ((ibuf [2] & 0xC0) >> 6);
??? obuf [3] = ibuf [2] & 0x3F;
??? switch(inputparts) {
??? case 1: /* only one byte read,?two '=' needed?*/
????? sprintf(output, "%c%c==",
????????????? table64[obuf[0]],
????????????? table64[obuf[1]]);
????? break;
??? case 2: /* two bytes read, one '=' needed */
????? sprintf(output, "%c%c%c=",
????????????? table64[obuf[0]],
????????????? table64[obuf[1]],
????????????? table64[obuf[2]]);
????? break;
??? default:
????? sprintf(output, "%c%c%c%c",
????????????? table64[obuf[0]],
????????????? table64[obuf[1]],
????????????? table64[obuf[2]],
????????????? table64[obuf[3]] );
????? break;
??? }
??? output += 4;
? }
? *output=0;
? *outbuf = base64data;
? return strlen(base64data);
}
?
-----------------------------
部分資料來自互聯網,轉載請注明作者及出處,謝謝!
轉載于:https://blog.51cto.com/freshpassport/619286
總結
以上是生活随笔為你收集整理的Base64编码解码与实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cisco 9月24日 CCNA实验
- 下一篇: 图象识别