前言
最近在做項(xiàng)目的時(shí)候用到了 base64 編碼,后面發(fā)現(xiàn)對(duì)這個(gè)東西一點(diǎn)都不了解,所以就查閱了下資料,這里做一個(gè)記錄
Base64
之所以稱為Base64編碼是因?yàn)樗褂昧?4個(gè)字符來對(duì)任意的數(shù)據(jù)進(jìn)行編碼,下面就是Base64的一個(gè)編碼表

Base64將一個(gè)8bit的字節(jié)序列拆位一個(gè)6位的片段,并且每個(gè)6位片段都能在上面的表中找到對(duì)應(yīng)的表示字符,為什么一個(gè)6位片段就能夠完整的表示正規(guī)的8個(gè)bit呢?8和6的最小公倍數(shù) 是24,也就是說3個(gè)傳統(tǒng)字節(jié)可以由4個(gè)Base64字符來表示,保證有效位數(shù)是一樣的,這樣就多了1/3的字節(jié)數(shù)來彌補(bǔ)Base64只有6個(gè)有效bit的不足,下面我們來個(gè)例子就能夠更好的理解其中的原理,我們以Man這個(gè)字符串為例,我們來看看其轉(zhuǎn)換后的Base64編碼是什么樣子的
| 文本 | M | a | n |
|---|---|---|---|
| ASCII編碼 | 77 | 97 | 110 |
| 二進(jìn)制位 | 01001101 | 01100001 | 01101110 |
對(duì)應(yīng)的我們將二進(jìn)制的8位化成6位為一個(gè)字節(jié)十進(jìn)制數(shù),并且找到其對(duì)應(yīng)的Base64編碼
| 劃為6位的二進(jìn)制 | 010011 | 010110 | 000101 | 101110 |
|---|---|---|---|---|
| 十進(jìn)制 | 19 | 22 | 5 | 46 |
| Base64 | T | W | F | U |
通過上面我們可以得出Man的base64編碼后的結(jié)果為TWFU,如果只有一個(gè)字節(jié)的字符的話就像下面這樣
| 文本 | A |
|---|---|
| 二進(jìn)制位 | 01000001 |
| 劃為6位的二進(jìn)制 | 010000 | 010000 | 000000 | 000000 |
|---|---|---|---|---|
| Base64 | Q | Q | = | = |
我們可以得出一個(gè)規(guī)律,一個(gè)字符都是三個(gè)字節(jié),三個(gè)字節(jié)的去轉(zhuǎn)換的,如果不夠三個(gè)字節(jié)后面就用0替代,其對(duì)應(yīng)的Base64編碼為=,所以我們?cè)诔R?guī)的Base64編碼發(fā)現(xiàn)最多不會(huì)超過兩個(gè)=,并且=也不會(huì)出現(xiàn)在編碼中間,都是出現(xiàn)在結(jié)尾部分。
通常我們?cè)陂_發(fā)中會(huì)遇到一些字符串的轉(zhuǎn)化,便可以通過以下方式來進(jìn)行
// 普通字符串 -> base64
NSString *man = @"Man";
NSString *base64String = [[man dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:0];
// base64 -> 普通字符串
NSData *normalData = [NSData alloc] initWithBase64EncodedString:base64String options:0];
NSString *normalString = [NSString alloc] initWithData:normalData encoding:NSUTF8StringEncoding];
結(jié)束
Base64編碼是從二進(jìn)制到字符的過程,可用于在HTTP環(huán)境下傳遞較長(zhǎng)的標(biāo)識(shí)信息。例如,在Java Persistence系統(tǒng)Hibernate中,就采用了Base64來將一個(gè)較長(zhǎng)的唯一標(biāo)識(shí)符(一般為128-bit的UUID)編碼為一個(gè)字符串,用作HTTP表單和HTTP GET URL中的參數(shù)。在其他應(yīng)用程序中,也常常需要把二進(jìn)制數(shù)據(jù)編碼為適合放在URL(包括隱藏表單域)中的形式。此時(shí),采用Base64編碼具有不可讀性,需要解碼后才能閱讀。
以上