Base64編碼方式在通信中的實際應用

加密就是為了安全通信而誕生的擅耽。沒有通信打毛,加密也沒有太大存在的意義司恳。

雖說Base64算不上一種加密途乃,只是一種具有固定標準的編碼方式,但如果適當?shù)淖儞Q一下編碼字典扔傅,不采用標準的編碼方式耍共,那對于不知道編碼字典的第三方來說就是一種加密方式烫饼。

用途

在介紹Base64編碼之前,我想先介紹下Base64的實際應用:

1)在前端中试读,當網(wǎng)頁上有數(shù)目龐大的圖片或其他資源時杠纵,瀏覽器會建立大量的http請求去獲取資源。這樣對服務器來說會產(chǎn)生大量的請求钩骇,浪費服務器性能比藻。對于客戶端來說,會多次請求資源倘屹,網(wǎng)絡利用率不高银亲,用戶體驗不好。所以纽匙,前端上有一個解決辦法就是群凶,對于大量的較小圖片采用雪碧圖(Sprite),一次將一張較大圖片加載回來,然后進行選擇展示哄辣。但是這樣會在js请梢、css、html代碼中增加很多附加代碼力穗,不利于后期操作與維護毅弧。于是,Base64的優(yōu)勢便顯現(xiàn)出來当窗,可以將圖片進行Base64編碼后嵌入到網(wǎng)頁中够坐,在展示時在將其進行Base64解碼,顯示在網(wǎng)頁上崖面。舉一個具體的實例:在google的首頁搜索框的搜索小圖標就是在用這樣的方式實現(xiàn)元咙。

2)迅雷的種子:),大家一定懂得巫员。為了不直接使下載鏈接暴露出來庶香,迅雷(旋風等下載工具)都會對鏈接進行Base64編碼。因為Base64編解碼規(guī)則是公開的简识,所以你只需要對迅雷的種子進行Base64解碼之后拿到下載鏈接赶掖,在別的地方下載,但是迅雷不會這樣單純的七扰。一般來說迅雷會對編碼表進行定制奢赂,在對編碼方式進行一個修改,這樣不知道規(guī)則的人就無法解密了颈走。

3)在只能發(fā)送字符的通信方式進行文件傳輸膳灶。文件是由一系列二進制數(shù)據(jù)組成,而字符集的編碼數(shù)量是小于byte的編碼數(shù)量的(ASCII:0127立由、BYTE:0255)轧钓。所以通過只能發(fā)字符的通信方式進行文件的傳輸看上去有些不可能司致,但是Base64恰恰解決的這個問題,Base64可以將byte映射到64個可見字符上聋迎。使用Base64將文件進行編碼脂矫,形成一個字符串,在將字符串傳給對方霉晕,對方收到后在進行解碼庭再,就可以還原出這個文件。

4)簡單的加密通信牺堰。本文開始時拄轻,提到Base64使用非標準的字典進行編碼時,對于第三方來說就是一種加密方式伟葫,對于第三方來說恨搓,想要破解,只能通過概率論來將編碼字典得出筏养。對于一些對加密效率要求高斧抱,而不要求太高的安全性的應用來說是一個比較好的選擇。

Base64是什么

Base64是基于64個可見字符的編碼方式渐溶,從Base64這個名字上可以得出辉浦。RCF文檔中對標準Base64的編碼字典規(guī)定為:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
‘=’最為填充字符
可以將任意二進制數(shù)映射到這64個字符中。

Base64的原理

舉一個實際的例子來說明:

情況一

對二進制 0x12 茎辐、0x34宪郊、0x56,進行Base64編碼拖陆。
1)00010010弛槐、0011010001010110依啰,每六個一組分為:000100乎串、100011010001孔飒、010110灌闺。
2)在計算機看來艰争,上述新分組后的值為:00000100坏瞄、0010001100010001甩卓、000101110鸠匀。相當于對每組數(shù)的高兩位進行了零填充,也就是說我們分完組之后的數(shù)所能表示的最大的范圍就是2^6 : 0 ~ 63逾柿,共64個數(shù)缀棍。

  1. 按照一一對應的方式宅此,在編碼字典中選取響應位置上的字符,分別是第12爬范、33父腕、1746位青瀑,查編碼字典為:M璧亮、hR斥难、u枝嘶。
    4)編碼后為:"MhRu"

最理想的情況是,待編碼的字節(jié)數(shù)是3的倍數(shù)哑诊,編碼后的字節(jié)數(shù)是4的倍數(shù)群扶,而上述展示的就是最理想的情況。

情況二

下面展示除3余1的情況:
對二進制0x12 镀裤、0x34竞阐、0x560x78暑劝,進行Base64編碼馁菜。
1)0001001000110100铃岔、01010110汪疮、01111000,每六個一組分為:000100毁习、100011智嚷、010001010110纺且、011110盏道、000000

  1. 在計算機看來,上述新分組后的值為:00000100载碌、00100011猜嘱、00010001000101110嫁艇、00011110朗伶、00000000
  2. 按照一一對應的方式步咪,在編碼字典中選取響應位置上的字符论皆,分別是第123317点晴、46感凤、0位,查編碼字典為:M粒督、h陪竿、Ru屠橄、e萨惑、A
  3. 為了滿足編碼后字節(jié)數(shù)為4的倍數(shù),需要在編碼后的字符后面添加'='填充符仇矾,M庸蔼、hR贮匕、u姐仅、eA刻盐、=掏膏、=
  4. 編碼后為:"MhRueA=="
情況三

下面展示除3余2的情況:
對二進制0x120x34敦锌、0x56馒疹、0x780x9a進行Base64編碼乙墙。

  1. 00010010颖变、0011010001010110听想、01111000腥刹、10011010,每六個一組分為:000100汉买、100011衔峰、010001010110蛙粘、011110垫卤、001001101000
  2. 在計算機看來出牧,上述新分組后的值為:00000100穴肘、0010001100010001崔列、000101110梢褐、00011110旺遮、00001001赵讯、00101000盈咳。
  3. 按照一一對應的方式,在編碼字典中選取響應位置上的字符边翼,分別是第12鱼响、3317组底、46丈积、309债鸡、40位江滨,查編碼字典為:Mh厌均、R唬滑、ue棺弊、J晶密、o
    4)為了滿足編碼后字節(jié)數(shù)為4的倍數(shù),需要在編碼后的字符后面添加'='填充符模她,M稻艰、hR侈净、u尊勿、eJ畜侦、o运怖、=
  4. 編碼后為:"MhRueJo="
而解碼就是編碼的逆過程

總結(jié)

可以看出,編碼前和編碼后的空間占用比在文件很大時為3:4的關系夏伊,小文件的占用比例會略大摇展。所以,Base64編碼的缺點就是空間占用比增大溺忧,消耗了cpu的資源進行編碼咏连。由于Base64編碼使用的都是可打印的普通字符,所以就能極大的減少在傳輸轉(zhuǎn)換中的錯誤率鲁森。

代碼實現(xiàn)


public class HFBase64 {
//編碼表祟滴,可以自定義,這樣只要雙方都知道編碼表歌溉,就變成一種加密方式了
    private static String encodingTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
    public HFBase64() {
        
    }
//編碼方法
    public String enCode(byte[] datas) {
        if (datas == null) {
            return null;
        }
        String ciphertext = "";
        Integer byteIndex = 0;
        while (byteIndex < datas.length) {
            Integer index = 0;
            byte[] temByte = new byte[3];
            byte temp;
            while (index < 3 && byteIndex < datas.length)
                temByte[index++] = datas[byteIndex++];
            ciphertext += encodingTable.charAt((temByte[0] & 0xfc) >> 2);
            ciphertext += encodingTable.charAt(((temByte[0] & 0x03) << 4) | ((temByte[1] & 0xf0) >> 4));
            if (index > 1) {
                ciphertext += encodingTable.charAt(((temByte[1] & 0x0f) << 2) | (temByte[2] & 0xc0) >> 6);
            } else {
                ciphertext += '=';
            }
            
            if (index > 2) {
                ciphertext += encodingTable.charAt((temByte[2] & 0x3f));
            } else {
                ciphertext += '=';
            }
        }
        
        return ciphertext;
    }
//解碼方法
    public byte[] deCode(String datas) {
        if (datas == null) {
            return null;
        }
        Integer len = (datas.length()) / 4 * 3;
        byte[] plainBytes = new byte[len];
        
        Integer charCount = 0;
        Integer index = 0;
        
        while (charCount < datas.length()) {
            
            plainBytes[index++] = (byte) ((this.convertByte(datas.charAt(charCount)) << 2) | (this.convertByte(datas.charAt(++charCount))) >> 4);
            if (datas.charAt(charCount + 1) == '=') {
//              plainBytes[--index] = (byte) (this.convertByte(datas.charAt(charCount)) >> 4);
                break;
            }
            plainBytes[index++] = (byte) ((this.convertByte(datas.charAt(charCount)) << 4) | (this.convertByte(datas.charAt(++charCount))) >> 2);
            if (datas.charAt(charCount + 1) == '=') {
//              plainBytes[--index] = (byte) (this.convertByte(datas.charAt(charCount)) >> 2);
                break;
            }
            plainBytes[index++] = (byte) ((this.convertByte(datas.charAt(charCount)) << 6) | (this.convertByte(datas.charAt(++charCount))));
            charCount++;
        }
        
        byte[] newBytes = new byte[index];
        for (int i = 0; i < index; i++) {
            newBytes[i] = plainBytes[i];
        }
        
        return newBytes;
    }
    
    private byte convertByte(char EncodeChar) {
        byte index = (byte) encodingTable.indexOf(EncodeChar);
        return index;
    }
}

代碼地址 點我
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垄懂,一起剝皮案震驚了整個濱河市骑晶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌草慧,老刑警劉巖桶蛔,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異漫谷,居然都是意外死亡仔雷,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門舔示,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碟婆,“玉大人,你說我怎么就攤上這事惕稻∈玻” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵俺祠,是天一觀的道長公给。 經(jīng)常有香客問我,道長锻煌,這世上最難降的妖魔是什么妓布? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮宋梧,結(jié)果婚禮上匣沼,老公的妹妹穿的比我還像新娘。我一直安慰自己捂龄,他們只是感情好释涛,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著倦沧,像睡著了一般唇撬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上展融,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天窖认,我揣著相機與錄音,去河邊找鬼告希。 笑死扑浸,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的燕偶。 我是一名探鬼主播喝噪,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼指么!你這毒婦竟也來了酝惧?” 一聲冷哼從身側(cè)響起榴鼎,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎晚唇,沒想到半個月后巫财,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡缺亮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年翁涤,在試婚紗的時候發(fā)現(xiàn)自己被綠了桥言。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片萌踱。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖号阿,靈堂內(nèi)的尸體忽然破棺而出并鸵,到底是詐尸還是另有隱情,我是刑警寧澤扔涧,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布园担,位于F島的核電站,受9級特大地震影響枯夜,放射性物質(zhì)發(fā)生泄漏弯汰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一湖雹、第九天 我趴在偏房一處隱蔽的房頂上張望咏闪。 院中可真熱鬧,春花似錦摔吏、人聲如沸鸽嫂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽据某。三九已至,卻和暖如春诗箍,著一層夾襖步出監(jiān)牢的瞬間癣籽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工滤祖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筷狼,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓氨距,卻偏偏與公主長得像桑逝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子俏让,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容