av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

JavaScript:詳解Base64編碼和解碼

Base64是最常用的編碼之一,比如開(kāi)發(fā)中用于傳遞參數(shù)、現(xiàn)代瀏覽器中的標(biāo)簽直接通過(guò)Base64字符串來(lái)渲染圖片以及用于郵件中等等。Base64編碼在RFC2045中定義,它被定義為:Base64內(nèi)容傳送編碼被設(shè)計(jì)用來(lái)把任意序列的8位字節(jié)描述為一種不易被人直接識(shí)別的形式。

創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)整合營(yíng)銷推廣、網(wǎng)站重做改版、蓋州網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5頁(yè)面制作、購(gòu)物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為蓋州等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

我們知道,任何數(shù)據(jù)在計(jì)算機(jī)中都是以二進(jìn)制的方式存儲(chǔ)的。一個(gè)字節(jié)為8位,一個(gè)字符在計(jì)算機(jī)中存儲(chǔ)為一個(gè)或多個(gè)字節(jié),比如英文字母、數(shù)字以及英文標(biāo)點(diǎn)符號(hào)就是用一個(gè) 字節(jié)來(lái)存儲(chǔ)的,通常稱為ASCII碼。而簡(jiǎn)體中文、繁體中文、日文以及韓文等都是用多字節(jié)來(lái)存儲(chǔ)的,通常稱為多字節(jié)字符。因?yàn)锽ase64編碼是對(duì)字符串的編碼表示進(jìn)行處理的,不同編碼的字符串的Base64的結(jié)果是不同的,所以我們需要了解基本的字符編碼知識(shí)。

字符編碼基礎(chǔ)

計(jì)算機(jī)最開(kāi)始只支持ASCII碼,一個(gè)字符用一個(gè)字節(jié)表示,只用了低7位,***位為0,因此總共有128個(gè)ASCII碼,范圍為0~127。后來(lái)為了支持多種地區(qū)的語(yǔ)言,各大組織機(jī)構(gòu)和IT廠商開(kāi)始發(fā)明它們自己的編碼方案,以便彌補(bǔ)ASCII編碼的不足,如GB2312編碼、GBK編碼和Big5編碼等。但這些編碼都只是針對(duì)局部地區(qū)或少數(shù)語(yǔ)言文字,沒(méi)有辦法表達(dá)所有的語(yǔ)言文字。而且這些不同的編碼之間并沒(méi)有任何聯(lián)系,它們之間的轉(zhuǎn)換需要通過(guò)查表來(lái)實(shí)現(xiàn)。

為了提高計(jì)算機(jī)的信息處理和交換功能,使得世界各國(guó)的文字都能在計(jì)算機(jī)中處理,從1984年起,ISO組織就開(kāi)始研究制定一個(gè)全新的標(biāo)準(zhǔn):通用多八位(即多字節(jié))編碼字符集(Universal Multiple-Octet Coded Character Set),簡(jiǎn)稱UCS。標(biāo)準(zhǔn)的編號(hào)為:ISO 10646。這一標(biāo)準(zhǔn)為世界各種主要語(yǔ)言的字符(包括簡(jiǎn)體及繁體的中文字)及附加符號(hào),編制統(tǒng)一的內(nèi)碼。

統(tǒng)一碼(Unicode)是Universal Code的縮寫,是由另一個(gè)叫“Unicode學(xué)術(shù)學(xué)會(huì)”(The Unicode Consortium)的機(jī)構(gòu)制定的字符編碼系統(tǒng)。Unicode與ISO 10646國(guó)際編碼標(biāo)準(zhǔn)從內(nèi)容上來(lái)說(shuō)是同步一致的。具體可參考:Unicode 。

ANSI

ANSI不代表具體的編碼,它是指本地編碼。比如在簡(jiǎn)體版windows上它表示GB2312編碼,在繁體版windows上它表示Big5編碼,在日文操作系統(tǒng)上它表示JIS編碼。所以如果您新建了個(gè)文本文件并保存為ANSI編碼,那么您現(xiàn)在應(yīng)該知道這個(gè)文件的編碼為本地編碼。

Unicode

Unicode編碼是和字符表一一映射的。比如56DE代表漢字'回',這種映射關(guān)系是固定不變的。通俗的說(shuō)Unicode編碼就是字符表的坐標(biāo),通過(guò)56DE就能找到漢字'回'。Unicode編碼的實(shí)現(xiàn)包括UTF8、UTF16、UTF32等等。

Unicode本身定義的就是每個(gè)字符的數(shù)值,是字符和自然數(shù)的映射關(guān)系,而UTF-8或者UTF-16甚至UTF-32則定義了如何在字節(jié)流中斷字,是計(jì)算機(jī)領(lǐng)域的概念。

通過(guò)上圖我們知道,UTF-8編碼為變長(zhǎng)的編碼方式,占1~6個(gè)字節(jié),可通過(guò)Unicode編碼值的區(qū)間來(lái)判斷,并且每個(gè)組成UTF8字符的字節(jié)都是有規(guī)律可循的。本文只討論UTF8和UTF16這兩種編碼。

UTF16

UTF16編碼使用固定的2個(gè)字節(jié)來(lái)存儲(chǔ)。因?yàn)槭嵌嘧止?jié)存儲(chǔ),所以它的存儲(chǔ)方式分為2種:大端序和小端序。UTF16編碼是Unicode最直接的實(shí)現(xiàn)方式,通常我們?cè)趙indows上新建文本文件后保存為Unicode編碼,其實(shí)就是保存為UTF16編碼。UTF16編碼在windows上采用小端序的方式存儲(chǔ),以下我新建了個(gè)文本文件并保存為Unicode編碼來(lái)測(cè)試,文件中只輸入了一個(gè)漢字'回',之后我用Editplus打開(kāi)它,切換到十六進(jìn)制方式查看,如圖所示:

我們看到有4個(gè)字節(jié),前2個(gè)字節(jié)FF FE是文件頭,表示這是一個(gè)UTF16編碼的文件,而DE 56則是'回'的UTF16編碼的十六進(jìn)制。我們經(jīng)常使用的JavaScript語(yǔ)言,它內(nèi)部就是采用UTF16編碼,并且它的存儲(chǔ)方式為大端序,來(lái)看一個(gè)例子:

 
 
  1. console.group('Test Unicode: ');
  2. console.log(('回'.charCodeAt(0)).toString(16).toUpperCase());

很明顯跟剛才Editplus顯示的不一樣,順序是相反的,這是因?yàn)樽止?jié)序不一樣。具體可參考:UTF-16 。

UTF8

UTF8是采用變長(zhǎng)的編碼方式,為1~6個(gè)字節(jié),但通常我們只把它看作單字節(jié)或三字節(jié)的實(shí)現(xiàn),因?yàn)槠渌闆r實(shí)在少見(jiàn)。UTF8編碼通過(guò)多個(gè)字節(jié)組合的方式來(lái)顯示,這是計(jì)算機(jī)處理UTF8的機(jī)制,它是無(wú)字節(jié)序之分的,并且每個(gè)字節(jié)都非常有規(guī)律,詳見(jiàn)上圖,在此不再詳述。

UTF16和UTF8的相互轉(zhuǎn)換

 

UTF16轉(zhuǎn)UTF8

UTF16和UTF8之間的相互轉(zhuǎn)換可以通過(guò)上圖的轉(zhuǎn)換表來(lái)實(shí)現(xiàn),判斷Unicode碼所在的區(qū)間就可以得到這個(gè)字符是由幾個(gè)字節(jié)所組成,之后通過(guò)移位來(lái)實(shí)現(xiàn)。我們用漢字'回'來(lái)舉一個(gè)轉(zhuǎn)換的例子。

我們已經(jīng)知道漢字'回'的Unicode碼是0x56DE,它介于U+00000800 – U+0000FFFF之間,所以它是用三個(gè)字節(jié)來(lái)表示的。

所以我們需要將0x56DE這個(gè)雙字節(jié)的值變?yōu)槿止?jié)的值,注意上圖中的x部分,就是對(duì)應(yīng)0x56DE的各位字節(jié),如果您數(shù)一下x的個(gè)數(shù),會(huì)發(fā)現(xiàn)剛好是16位。

轉(zhuǎn)換思路

從0x56DE中取出4位放在低位,并和二進(jìn)制的1110結(jié)合,這就是***個(gè)字節(jié)。從0x56DE中剩下的字節(jié)中取出6位放在低位,并和二進(jìn)制的10結(jié)合,這就是第二個(gè)字節(jié)。第三個(gè)字節(jié)依照類似的方式實(shí)現(xiàn)。

代碼實(shí)現(xiàn)

為了讓大家更好的理解,以下代碼只是實(shí)現(xiàn)漢字'回'的轉(zhuǎn)換,代碼如下:

 
 
  1. /**
  2. * 轉(zhuǎn)換對(duì)照表
  3. * U+00000000 – U+0000007F   0xxxxxxx
  4. * U+00000080 – U+000007FF   110xxxxx 10xxxxxx
  5. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  6. * U+00010000 – U+001FFFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  7. * U+00200000 – U+03FFFFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  8. * U+04000000 – U+7FFFFFFF   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  9. */
  10. /*
  11. * '回'的Unicode編碼為:0x56DE,它介于U+00000800 – U+0000FFFF之間,所以它占用三個(gè)字節(jié)。
  12. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  13. */
  14. var ucode = 0x56DE;
  15. // 1110xxxx
  16. var byte1 = 0xE0 | ((ucode >> 12) & 0x0F);
  17. // 10xxxxxx
  18. var byte2 = 0x80 | ((ucode >> 6) & 0x3F);
  19. // 10xxxxxx
  20. var byte3 = 0x80 | (ucode & 0x3F);
  21. var utf8 = String.fromCharCode(byte1)
  22.         + String.fromCharCode(byte2)
  23.         + String.fromCharCode(byte3);
  24. console.group('Test UTF16ToUTF8: ');
  25. console.log(utf8);
  26. console.groupEnd();

輸出的結(jié)果看起來(lái)像亂碼,這是因?yàn)镴avaScript不知道如何顯示UTF8的字符。您或許會(huì)說(shuō)輸出不正常轉(zhuǎn)換還有什么用,但您應(yīng)該知道轉(zhuǎn)換的目的還經(jīng)常用于傳輸或API的需要。

UTF8轉(zhuǎn)UTF16

這是UTF16轉(zhuǎn)換到UTF8的逆轉(zhuǎn)換,同樣需要對(duì)照轉(zhuǎn)換表來(lái)實(shí)現(xiàn)。還是接上一個(gè)例子,我們已經(jīng)得到了漢字'回'的UTF8編碼,這是三個(gè)字節(jié)的,我們只需要按照轉(zhuǎn)換表來(lái)轉(zhuǎn)成雙字節(jié)的,如圖所示,我們需要保留下所有的x。

代碼如下:

 
 
  1. /**
  2. * 轉(zhuǎn)換對(duì)照表
  3. * U+00000000 – U+0000007F   0xxxxxxx
  4. * U+00000080 – U+000007FF   110xxxxx 10xxxxxx
  5. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  6. * U+00010000 – U+001FFFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  7. * U+00200000 – U+03FFFFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  8. * U+04000000 – U+7FFFFFFF   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  9. */
  10. /*
  11. * '回'的Unicode編碼為:0x56DE,它介于U+00000800 – U+0000FFFF之間,所以它占用三個(gè)字節(jié)。
  12. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  13. */
  14. var ucode = 0x56DE;
  15. // 1110xxxx
  16. var byte1 = 0xE0 | ((ucode >> 12) & 0x0F);
  17. // 10xxxxxx
  18. var byte2 = 0x80 | ((ucode >> 6) & 0x3F);
  19. // 10xxxxxx
  20. var byte3 = 0x80 | (ucode & 0x3F);
  21. var utf8 = String.fromCharCode(byte1)
  22.         + String.fromCharCode(byte2)
  23.         + String.fromCharCode(byte3);
  24. console.group('Test UTF16ToUTF8: ');
  25. console.log(utf8);
  26. console.groupEnd();
  27. /** ------------------------------------------------------------------------------------*/
  28. // 由三個(gè)字節(jié)組成,所以分別取出
  29. var c1 = utf8.charCodeAt(0);
  30. var c2 = utf8.charCodeAt(1);
  31. var c3 = utf8.charCodeAt(2);
  32. /*
  33. * 需要通過(guò)判斷特定位的方式來(lái)轉(zhuǎn)換,但這里是已知是三個(gè)字節(jié),所以忽略判斷,而是直接拿到所有的x,組成16位。
  34. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  35. */
  36. // 丟棄***個(gè)字節(jié)的高四位并和第二個(gè)字節(jié)的高四位組成一個(gè)字節(jié)
  37. var b1 = (c1 << 4) | ((c2 >> 2) & 0x0F);
  38. // 同理第二個(gè)字節(jié)和第三個(gè)字節(jié)組合
  39. var b2 = ((c2 & 0x03) << 6) | (c3 & 0x3F);
  40. // 將b1和b2組成16位
  41. var ucode = ((b1 & 0x00FF) << 8) | b2;
  42. console.group('Test UTF8ToUTF16: ');
  43. console.log(ucode.toString(16).toUpperCase(), String.fromCharCode(ucode));
  44. console.groupEnd();

知道了轉(zhuǎn)換規(guī)則,就很容易實(shí)現(xiàn)了。

Base64編碼

Base64編碼要求把3個(gè)8位字節(jié)(3*8=24)轉(zhuǎn)化為4個(gè)6位的字節(jié)(4*6=24),之后在6位的前面補(bǔ)兩個(gè)0,形成8位一個(gè)字節(jié)的形式。由于2的6次方為64,所以每6個(gè)位為一個(gè)單元,對(duì)應(yīng)某個(gè)可打印字符。當(dāng)原數(shù)據(jù)不是3的整數(shù)倍時(shí),如果***剩下兩個(gè)輸入數(shù)據(jù),在編碼結(jié)果后加1個(gè)“=;如果***剩下一個(gè)輸入數(shù)據(jù),編碼結(jié)果后加2個(gè)“=;如果沒(méi)有剩下任何數(shù)據(jù),就什么都不要加,這樣才可以保證資料還原的正確性。

轉(zhuǎn)碼對(duì)照表

每6個(gè)單元高位補(bǔ)2個(gè)零形成的字節(jié)位于0~63之間,通過(guò)在轉(zhuǎn)碼表中查找對(duì)應(yīng)的可打印字符。“=”用于填充。如下圖所示為轉(zhuǎn)碼表。

具體可參考: Base64 。

#p#

Base64解碼

解碼是編碼的逆過(guò)程,先看后面補(bǔ)了幾個(gè)“=”號(hào),最多只可能補(bǔ)2個(gè)“=”號(hào)。一個(gè)“=”相當(dāng)于補(bǔ)了2個(gè)0,所以去掉后面補(bǔ)的0后,再按8位展開(kāi),即可還原。

JavaScript實(shí)現(xiàn)Base64的編碼和解碼

之前已經(jīng)詳細(xì)講解了整個(gè)過(guò)程,本文的例子都是采用UTF8編碼的字符串作為Base64編碼的基礎(chǔ)。因?yàn)镴avaScript內(nèi)部是使用Unicode編碼,所以需要有個(gè)轉(zhuǎn)換過(guò)程,原理之前也詳細(xì)講解過(guò)并給出了示例,以下是代碼實(shí)現(xiàn):

 
 
  1. /**
  2. * UTF16和UTF8轉(zhuǎn)換對(duì)照表
  3. * U+00000000 – U+0000007F   0xxxxxxx
  4. * U+00000080 – U+000007FF   110xxxxx 10xxxxxx
  5. * U+00000800 – U+0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
  6. * U+00010000 – U+001FFFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  7. * U+00200000 – U+03FFFFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  8. * U+04000000 – U+7FFFFFFF   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  9. */
  10. var Base64 = {
  11.     // 轉(zhuǎn)碼表
  12.     table : [
  13.             'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  14.             'I', 'J', 'K', 'L', 'M', 'N', 'O' ,'P',
  15.             'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
  16.             'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  17.             'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
  18.             'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  19.             'w', 'x', 'y', 'z', '0', '1', '2', '3',
  20.             '4', '5', '6', '7', '8', '9', '+', '/'
  21.     ],
  22.     UTF16ToUTF8 : function(str) {
  23.         var res = [], len = str.length;
  24.         for (var i = 0; i < len; i++) {
  25.             var code = str.charCodeAt(i);
  26.             if (code > 0x0000 && code <= 0x007F) {
  27.                 // 單字節(jié),這里并不考慮0x0000,因?yàn)樗强兆止?jié)
  28.                 // U+00000000 – U+0000007F  0xxxxxxx
  29.                 res.push(str.charAt(i));
  30.             } else if (code >= 0x0080 && code <= 0x07FF) {
  31.                 // 雙字節(jié)
  32.                 // U+00000080 – U+000007FF  110xxxxx 10xxxxxx
  33.                 // 110xxxxx
  34.                 var byte1 = 0xC0 | ((code >> 6) & 0x1F);
  35.                 // 10xxxxxx
  36.                 var byte2 = 0x80 | (code & 0x3F);
  37.                 res.push(
  38.                     String.fromCharCode(byte1), 
  39.                     String.fromCharCode(byte2)
  40.                 );
  41.             } else if (code >= 0x0800 && code <= 0xFFFF) {
  42.                 // 三字節(jié)
  43.                 // U+00000800 – U+0000FFFF  1110xxxx 10xxxxxx 10xxxxxx
  44.                 // 1110xxxx
  45.                 var byte1 = 0xE0 | ((code >> 12) & 0x0F);
  46.                 // 10xxxxxx
  47.                 var byte2 = 0x80 | ((code >> 6) & 0x3F);
  48.                 // 10xxxxxx
  49.                 var byte3 = 0x80 | (code & 0x3F);
  50.                 res.push(
  51.                     String.fromCharCode(byte1), 
  52.                     String.fromCharCode(byte2), 
  53.                     String.fromCharCode(byte3)
  54.                 );
  55.             } else if (code >= 0x00010000 && code <= 0x001FFFFF) {
  56.                 // 四字節(jié)
  57.                 // U+00010000 – U+001FFFFF  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  58.             } else if (code >= 0x00200000 && code <= 0x03FFFFFF) {
  59.                 // 五字節(jié)
  60.                 // U+00200000 – U+03FFFFFF  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  61.             } else /** if (code >= 0x04000000 && code <= 0x7FFFFFFF)*/ {
  62.                 // 六字節(jié)
  63.                 // U+04000000 – U+7FFFFFFF  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  64.             }
  65.         }
  66.         return res.join('');
  67.     },
  68.     UTF8ToUTF16 : function(str) {
  69.         var res = [], len = str.length;
  70.         var i = 0;
  71.         for (var i = 0; i < len; i++) {
  72.             var code = str.charCodeAt(i);
  73.             // 對(duì)***個(gè)字節(jié)進(jìn)行判斷
  74.             if (((code >> 7) & 0xFF) == 0x0) {
  75.                 // 單字節(jié)
  76.                 // 0xxxxxxx
  77.                 res.push(str.charAt(i));
  78.             } else if (((code >> 5) & 0xFF) == 0x6) {
  79.                 // 雙字節(jié)
  80.                 // 110xxxxx 10xxxxxx
  81.                 var code2 = str.charCodeAt(++i);
  82.                 var byte1 = (code & 0x1F) << 6;
  83.                 var byte2 = code2 & 0x3F;
  84.                 var utf16 = byte1 | byte2;
  85.                 res.push(Sting.fromCharCode(utf16));
  86.             } else if (((code >> 4) & 0xFF) == 0xE) {
  87.                 // 三字節(jié)
  88.                 // 1110xxxx 10xxxxxx 10xxxxxx
  89.                 var code2 = str.charCodeAt(++i);
  90.                 var code3 = str.charCodeAt(++i);
  91.                 var byte1 = (code << 4) | ((code2 >> 2) & 0x0F);
  92.                 var byte2 = ((code2 & 0x03) << 6) | (code3 & 0x3F);
  93.                 utf16 = ((byte1 & 0x00FF) << 8) | byte2
  94.                 res.push(String.fromCharCode(utf16));
  95.             } else if (((code >> 3) & 0xFF) == 0x1E) {
  96.                 // 四字節(jié)
  97.                 // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  98.             } else if (((code >> 2) & 0xFF) == 0x3E) {
  99.                 // 五字節(jié)
  100.                 // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  101.             } else /** if (((code >> 1) & 0xFF) == 0x7E)*/ {
  102.                 // 六字節(jié)
  103.                 // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  104.             }
  105.         }
  106.         return res.join('');
  107.     },
  108.     encode : function(str) {
  109.         if (!str) {
  110.             return '';
  111.         }
  112.         var utf8    = this.UTF16ToUTF8(str); // 轉(zhuǎn)成UTF8
  113.         var i = 0; // 遍歷索引
  114.         var len = utf8.length;
  115.         var res = [];
  116.         while (i < len) {
  117.             var c1 = utf8.charCodeAt(i++) & 0xFF;
  118.             res.push(this.table[c1 >> 2]);
  119.             // 需要補(bǔ)2個(gè)=
  120.             if (i == len) {
  121.                 res.push(this.table[(c1 & 0x3) << 4]);
  122.                 res.push('==');
  123.                 break;
  124.             }
  125.             var c2 = utf8.charCodeAt(i++);
  126.             // 需要補(bǔ)1個(gè)=
  127.             if (i == len) {
  128.                 res.push(this.table[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
  129.                 res.push(this.table[(c2 & 0x0F) << 2]);
  130.                 res.push('=');
  131.                 break;
  132.             }
  133.             var c3 = utf8.charCodeAt(i++);
  134.             res.push(this.table[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
  135.             res.push(this.table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]);
  136.             res.push(this.table[c3 & 0x3F]);
  137.         }
  138.         return res.join('');
  139.     },
  140.     decode : function(str) {
  141.         if (!str) {
  142.             return '';
  143.         }
  144.         var len = str.length;
  145.         var i   = 0;
  146.         var res = [];
  147.         while (i < len) {
  148.             code1 = this.table.indexOf(str.charAt(i++));
  149.             code2 = this.table.indexOf(str.charAt(i++));
  150.             code3 = this.table.indexOf(str.charAt(i++));
  151.             code4 = this.table.indexOf(str.charAt(i++));
  152.             c1 = (code1 << 2) | (code2 >> 4);
  153.             c2 = ((code2 & 0xF) << 4) | (code3 >> 2);
  154.             c3 = ((code3 & 0x3) << 6) | code4;
  155.             res.push(String.fromCharCode(c1));
  156.             if (code3 != 64) {
  157.                 res.push(String.fromCharCode(c2));
  158.             }
  159.             if (code4 != 64) {
  160.                 res.push(String.fromCharCode(c3));
  161.             }
  162.         }
  163.         return this.UTF8ToUTF16(res.join(''));
  164.     }
  165. };
  166. console.group('Test Base64: ');
  167. var b64 = Base64.encode('Hello, oschina!又是一年春來(lái)到~');
  168. console.log(b64);
  169. console.log(Base64.decode(b64));
  170. console.groupEnd();

不得不說(shuō),在JavaScript中實(shí)現(xiàn)確實(shí)很麻煩。我們來(lái)看下PHP對(duì)同樣的字符串編碼的結(jié)果:

因?yàn)樽址幋a是一樣的,所以結(jié)果也一樣。


網(wǎng)站欄目:JavaScript:詳解Base64編碼和解碼
當(dāng)前鏈接:http://uogjgqi.cn/article/dpihhds.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流