最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文講清base64編碼原理

 更新時(shí)間:2023年03月01日 09:11:03   作者:JyLie  
本文主要介紹了一文講清base64編碼原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

平靜之下,驀然回首,base64 卻在燈火闌珊處。

今天翻開舊項(xiàng)目發(fā)現(xiàn)挺多圖片相關(guān)的插件都是用 base64 來顯示圖片的。談到 base64,腦海遐想翩翩,思緒回蕩之下 base64 瑕瑜互見。本文旨在記錄工作中遇見的問題并加以總結(jié),如有不妥請(qǐng)指正~

base64 由來

base64 是網(wǎng)絡(luò)傳輸 8Bit 字節(jié)代碼的編碼方式之一,是一種基于 64 個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的方法。在做支付系統(tǒng)時(shí),報(bào)文交互都需要使用 base64 對(duì)明文進(jìn)行轉(zhuǎn)碼,然后再進(jìn)行簽名或加密,之后再進(jìn)行(或再次 base64 轉(zhuǎn)碼)傳輸。那么,base64 到底起到什么作用呢?

在參數(shù)傳輸?shù)倪^程中經(jīng)常遇到的一種情況:使用全英文的字符串沒問題,但一旦涉及到中文就會(huì)出現(xiàn)亂碼的情況。與此類似,網(wǎng)絡(luò)上傳輸?shù)淖址⒉蝗强纱蛴〉淖址?,比如二進(jìn)制文件、圖片等。base64 的出現(xiàn)就是為了解決此問題,它是基于 64 個(gè)可打印的字符來表示二進(jìn)制的數(shù)據(jù)的一種方法。

電子郵件剛問世的時(shí)候,只能傳輸英文,但后來隨著用戶的增加,中文、日韓俄文等文字的用戶也有需求,但這些字符并不能被服務(wù)器或網(wǎng)關(guān)有效處理,因此 base64 就登場(chǎng)了。隨后,base64 在 URL、Cookie、網(wǎng)頁(yè)傳輸少量二進(jìn)制文件中也有相應(yīng)的使用。

base64 的編碼原理

基于a-zA-Z、0-9+/這 64 個(gè)字符來標(biāo)識(shí)二進(jìn)制數(shù)據(jù),另外=符號(hào)用于當(dāng)字節(jié)缺位時(shí)補(bǔ)用。

base64 編碼對(duì)照表

base64 編碼對(duì)照表

索引

對(duì)應(yīng)字符

索引

對(duì)應(yīng)字符

索引

對(duì)應(yīng)字符

索引

對(duì)應(yīng)字符

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

15

P

32

g

49

x

16

Q

33

h

50

y

base64 的編碼轉(zhuǎn)換規(guī)則

base64 要求把每三個(gè) 8Bit 的字節(jié)轉(zhuǎn)換四個(gè) 6Bit 的字節(jié)(3*8 = 4*6 = 24),然后把 6Bit再添兩位高位 0,組成四個(gè) 8Bit 的字節(jié)(4*8=32)。

為什么使用 3 個(gè)字節(jié)一組呢?因?yàn)?6 和 8 的最小公倍數(shù)為 24,三個(gè)字節(jié)正好 24 個(gè)二進(jìn)制位,每 6 個(gè) bit 位一組,恰好能夠分為 4 組。

同時(shí)用于分組后每組添加兩個(gè)高位 0,轉(zhuǎn)換后的字符串理論上將要比原來的字符長(zhǎng) 1/3(24/32=1/3)

  • 步驟分解:

    將待轉(zhuǎn)換的字符串每三個(gè)字符分為一組,每個(gè)字符字節(jié)占 8bit,那么共有 24 個(gè)二進(jìn)制位。

    將 24 個(gè)二進(jìn)制位每 6 個(gè)字節(jié)為一組,共分為 4 組。

    在每組 6 字節(jié)前面添加兩個(gè) 0,每組由 6 字節(jié)變?yōu)?8 字節(jié)二進(jìn)制位,組成總共 32 個(gè)二進(jìn)制位,即四個(gè)字節(jié)。

    根據(jù) base64 編碼對(duì)照表獲得對(duì)應(yīng)的值。

  • 舉個(gè)栗子

    • 以標(biāo)準(zhǔn) 3 個(gè)字符LJY為例。

    LJY 對(duì)應(yīng)的 ASCII 碼值分別為 76、74、89,對(duì)應(yīng)的二進(jìn)制值是 01001100、01001010、01011001。由此組成一個(gè) 24 位的二進(jìn)制位字符串。

    將 24 位的二進(jìn)制位字符串,按照每 6 位二進(jìn)制位一組分成 4 組。

    對(duì) 4 組 每組 6 位二進(jìn)制位字符串前面補(bǔ)兩個(gè) 0,每組擴(kuò)展為 8 位二進(jìn)制位,4 組共擴(kuò)展成 32 個(gè)二進(jìn)制位,此時(shí) 4 組二進(jìn)制位分別為:00010011、00000100、00101001、00011001。其對(duì)應(yīng)的 base64 編碼索引為:19、4、41、25。

    用 base64 編碼索引值在 base64 編碼表中進(jìn)行查找,分別對(duì)應(yīng):T、E、p、Z。

    • 因此LJYbase64 編碼之后就變?yōu)椋篢EpZ。
|   文本           |    L     |    J     |    Y     |
|  ASCII          |    76    |    74    |    89    |
| 二進(jìn)制位         | 01001100 | 01001010 | 01011001 |
| 分組二進(jìn)制       | 010011   | 000100   | 101001   | 011001   |
| 分組二進(jìn)制補(bǔ)2個(gè)0 | 00010011 | 00000100 | 00101001 | 00011001 |
| 分組索引         |   19     |   4      |   41     |   25     |
| base64編碼       |   T     |   E      |    p      |   Z      |

主要展示:
轉(zhuǎn)換前二進(jìn)制位: 01001100 01001010 01011001
轉(zhuǎn)換后二進(jìn)制位: 00010011 00000100 00101001 00011001
復(fù)制代碼
  • 字符位數(shù)不足情況

上述栗子是面向剛好三個(gè)字符為一組的情況。當(dāng)然不是所有時(shí)候都這么巧字符位數(shù)足夠,除此以外有位數(shù)不足的情況。那么,面對(duì)字符位數(shù)不足的情況下該如何處理呢?

base64 給出的方案是,當(dāng)每組字符不足三位時(shí),不足位數(shù)位置需要使用=符號(hào)補(bǔ)上。

位數(shù)不足情況處理情景:

  • 位數(shù)缺一個(gè)字節(jié):一個(gè)字節(jié)共 8 個(gè)二進(jìn)制位,依舊按照規(guī)則進(jìn)行分組。此時(shí)共 8 個(gè)二進(jìn)制位,每 6 個(gè)一組,則第二組缺少 4 位,用 0 補(bǔ)齊,得到兩個(gè) base64 編碼,而后面兩組沒有對(duì)應(yīng)數(shù)據(jù),都用=補(bǔ)上。
  • 位數(shù)缺兩個(gè)字節(jié):兩個(gè)字節(jié)共 16 個(gè)二進(jìn)制位,依舊按照規(guī)則進(jìn)行分組。此時(shí)總共 16 個(gè)二進(jìn)制位,每 6 個(gè)一組,則第三組缺少 2 位,用 0 補(bǔ)齊,得到三個(gè) base64 編碼,第四組完全沒有數(shù)據(jù)則用=補(bǔ)上。

位數(shù)不足圖解如下:

<!-- 缺2位字符,字符串以A為例轉(zhuǎn)換base64后位QQ== -->
|   文本(1Byte)  |    A     |          |          |
| 二進(jìn)制位         | 01000001 |          |          |
| 分組二進(jìn)制       | 010000   | 010000   |          |          |
| 分組二進(jìn)制補(bǔ)0    | 00010000 | 00010000 |          |          |
| 分組索引         |   16     |   16     |          |          |
| base64編碼       |   Q     |   Q      |    =      |   =      |

<!-- 缺1位字符,字符串以AB為例轉(zhuǎn)換base64后位QUI= -->
|   文本(1Byte)  |    A     |     B    |          |
| 二進(jìn)制位         | 01000001 | 01000010 |          |
| 分組二進(jìn)制       | 010000   | 010100   |  001000  |          |
| 分組二進(jìn)制補(bǔ)0    | 00010000 | 00010100 | 00001000 |          |
| 分組索引         |   16     |   20     |    8      |          |
| base64編碼       |   Q     |   U      |    I      |   =      |
復(fù)制代碼

列舉了一個(gè)字符到三個(gè)字符轉(zhuǎn)換為 base64 ,可以發(fā)現(xiàn)將 base64 就是按照 base64 編碼對(duì)照表來將二進(jìn)制轉(zhuǎn)換為字符串,使得數(shù)據(jù)不能直接明文展示出來,但也算不上是加密,而這巧好可用在傳輸、存儲(chǔ)、表示二進(jìn)制領(lǐng)域的情景。

  • 另外值得注意的是,不用語(yǔ)言如中文有多種編碼(比如:utf-8、gb2312、gbk 等),不同編碼對(duì)應(yīng) base64 編碼結(jié)果都不一樣。
  • 其次在推演過程中可發(fā)現(xiàn) base64 即用 6 位字節(jié)(2 的 6 次冪就是 64)表示字符同理,Base32 就是用 5 位字節(jié),Base16 就是用 4 位字節(jié)。大家可以按照上面的步驟進(jìn)行演化測(cè)試。

base64 優(yōu)缺點(diǎn)

知道 base64 是什么后,也該到為什么出現(xiàn)了。為什么要是使用 base64 呢,這要從其優(yōu)缺點(diǎn)入手來選擇適合場(chǎng)景了。

  • 優(yōu)勢(shì):
    • base64 適合不同平臺(tái)、不同語(yǔ)言的傳輸;
    • 頁(yè)面中內(nèi)嵌使用 base64 格式的小圖片,可減少了服務(wù)器訪問次數(shù);
    • 二進(jìn)制位轉(zhuǎn)換 base64 算法簡(jiǎn)單,對(duì)性能影響不大;
  • 缺點(diǎn)
    • 二進(jìn)制文件轉(zhuǎn)換為 base64 后,體積大概增加 1/3;
      • 在基于 Android6.0 及以下默認(rèn)瀏覽器實(shí)測(cè)場(chǎng)景中發(fā)現(xiàn),某些機(jī)型如中興上傳 base64 圖片會(huì)因?yàn)樽址笮∵^大導(dǎo)致上傳奔潰的情況。
      • 字符長(zhǎng)度過大的 base64 不適應(yīng)使用在 URL 情景,因?yàn)?IOS 端瀏覽器會(huì)限制 URL 長(zhǎng)度,當(dāng)長(zhǎng)度超過時(shí)會(huì)自動(dòng)切除多余部分,導(dǎo)致數(shù)據(jù)丟失。
      • base64 字符過大會(huì)導(dǎo)致頁(yè)面加載速度變慢,因此建議 10kb 以下的圖片使用。
    • base64 無(wú)法緩存,要緩存只能緩存包含 base64 的文件,比如 js 或者 css;
    • 面對(duì)大文件時(shí),會(huì)消耗一定的 CPU 進(jìn)行編解碼

JavaScript 的 base64 轉(zhuǎn)碼方法

Web API 二進(jìn)制與 base64 轉(zhuǎn)換

  • atob(encodedData) : 解碼一個(gè) base64 編碼的字符串。

enCodedData,是一個(gè)通過 btoa() 方法編碼的字符串, 為二進(jìn)制字符串包含 base64 編碼的數(shù)據(jù)。并返回包含來自 encodedData 的解碼數(shù)據(jù)的 ASCII 字符串。

  • btoa(stringToEncode) : 創(chuàng)建一個(gè) bas64 編碼的字符串。

stringToEncode 為要編碼的二進(jìn)制字符串。并返回包含 stringToEncode 的 base64 表示形式的 ASCII 字符串。

另外在 JavaScript 中,字符串使用 UTF-16 字符編碼表示:在這種編碼中,字符串表示為 16 位(2 字節(jié))單元的序列。每個(gè) ASCII 字符都可以放入其中一個(gè)單元的第一個(gè)字節(jié),但許多其他字符不能。

base64 在設(shè)計(jì)上需要二進(jìn)制數(shù)據(jù)作為其輸入。就 JavaScript 字符串而言,這意味著每個(gè)字符只占用一個(gè)字節(jié)的字符串。因此,如果將一個(gè)字符串傳遞到 btoa()中,其中包含占用多個(gè)字節(jié)的字符,則會(huì)出現(xiàn)錯(cuò)誤,因?yàn)檫@不被視為二進(jìn)制數(shù)據(jù),因此超 16 位字符在使用 btoa()時(shí)需要先對(duì)字符轉(zhuǎn)碼為二進(jìn)制位。

// 簡(jiǎn)單數(shù)據(jù)
const encodedData = btoa('Hello, world'); // encode a string
const decodedData = atob(encodedData); // decode the string

/* 復(fù)雜數(shù)據(jù) */
// convert a Unicode string to a string in which
// each 16-bit unit occupies only one byte
function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i < codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  const charCodes = new Uint8Array(codeUnits.buffer);
  let result = '';
  for (let i = 0; i < charCodes.byteLength; i++) {
    result += String.fromCharCode(charCodes[i]);
  }
  return result;
}
function fromBinary(binary) {
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  const charCodes = new Uint16Array(bytes.buffer);
  let result = '';
  for (let i = 0; i < charCodes.length; i++) {
    result += String.fromCharCode(charCodes[i]);
  }
  return result;
}

// a string that contains characters occupying > 1 byte
const myString = '???????';

const converted = toBinary(myString);
const encoded = btoa(converted);
console.log(encoded); // OCY5JjomOyY8Jj4mPyY=

const decoded = atob(encoded);
const original = fromBinary(decoded);
console.log(original); // ???????
  • 兼容性:atob() 方法不支持 IE9 及更早的 IE 版本。

base64 轉(zhuǎn)二進(jìn)制

// base64編碼表
const map = {
  0: 52,
  1: 53,
  2: 54,
  3: 55,
  4: 56,
  5: 57,
  6: 58,
  7: 59,
  8: 60,
  9: 61,
  A: 0,
  B: 1,
  C: 2,
  D: 3,
  E: 4,
  F: 5,
  G: 6,
  H: 7,
  I: 8,
  J: 9,
  K: 10,
  L: 11,
  M: 12,
  N: 13,
  O: 14,
  P: 15,
  Q: 16,
  R: 17,
  S: 18,
  T: 19,
  U: 20,
  V: 21,
  W: 22,
  X: 23,
  Y: 24,
  Z: 25,
  a: 26,
  b: 27,
  c: 28,
  d: 29,
  e: 30,
  f: 31,
  g: 32,
  h: 33,
  i: 34,
  j: 35,
  k: 36,
  l: 37,
  m: 38,
  n: 39,
  o: 40,
  p: 41,
  q: 42,
  r: 43,
  s: 44,
  t: 45,
  u: 46,
  v: 47,
  w: 48,
  x: 49,
  y: 50,
  z: 51,
  '+': 62,
  '/': 63,
};

function base64to2(base64) {
  let len = base64.length * 0.75; // 轉(zhuǎn)換為int8array所需長(zhǎng)度
  base64 = base64.replace(/=*$/, ''); // 去掉=號(hào)(占位的)

  const int8 = new Int8Array(len); //設(shè)置int8array視圖
  let arr1,
    arr2,
    arr3,
    arr4,
    p = 0;

  for (let i = 0; i < base64.length; i += 4) {
    arr1 = map[base64[i]]; // 每次循環(huán) 都將base644個(gè)字節(jié)轉(zhuǎn)換為3個(gè)int8array直接
    arr2 = map[base64[i + 1]];
    arr3 = map[base64[i + 2]];
    arr4 = map[base64[i + 3]];
    // 假設(shè)數(shù)據(jù)arr 數(shù)據(jù) 00101011 00101111 00110011 00110001
    int8[p++] = (arr1 << 2) | (arr2 >> 4);
    // 上面的操作 arr1向左邊移動(dòng)2位 變?yōu)?0101100
    // arr2 向右移動(dòng)4位:00000010
    // | 為'與'操作: 10101110
    int8[p++] = (arr2 << 4) | (arr3 >> 2);
    int8[p++] = (arr3 << 6) | arr4;
  }
  return int8;
}

base64 轉(zhuǎn)成 Blob

// base64圖片轉(zhuǎn)blob
function base64toBlob(base64) {
  var arr = base64.split(','),
    mime = arr[0].match(/:(.*?);/)[1] || 'image/png',
    bstr = atob(arr[1]), // 將base64轉(zhuǎn)為Unicode規(guī)則編碼
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n); // 轉(zhuǎn)換編碼后才可以使用charCodeAt 找到Unicode編碼
  }
  return new Blob([u8arr], { type: mime });
}

/* 優(yōu)化版 */
function base64ToBlob(base64) {
  var arr = base64.split(',');
  var mime = arr[0].match(/:(.*?);/)[1] || 'image/png';
  // 去掉url的頭,并轉(zhuǎn)化為byte
  var bytes = window.atob(arr[1]);
  // 處理異常,將ascii碼小于0的轉(zhuǎn)換為大于0
  var ab = new ArrayBuffer(bytes.length);
  // 生成視圖(直接針對(duì)內(nèi)存):8位無(wú)符號(hào)整數(shù),長(zhǎng)度1個(gè)字節(jié)
  var u8arr = new Uint8Array(ab);

  for (var i = 0; i < bytes.length; i++) {
    u8arr[i] = bytes.charCodeAt(i);
  }

  return new Blob([u8arr], { type: mime });
}

相關(guān)文獻(xiàn)

到此這篇關(guān)于一文講清base64編碼原理的文章就介紹到這了,更多相關(guān)base64編碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • gliffy UML工具安裝使用過程

    gliffy UML工具安裝使用過程

    這篇文章主要介紹了gliffy UML工具安裝使用過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • 詳解使用內(nèi)網(wǎng)穿透工具Ngrok代理本地服務(wù)

    詳解使用內(nèi)網(wǎng)穿透工具Ngrok代理本地服務(wù)

    本文主要介紹了使用內(nèi)網(wǎng)穿透工具Ngrok代理本地服務(wù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-03-03
  • 趣談Unicode、Ascii、utf-8、GB2312、GBK等編碼知識(shí)

    趣談Unicode、Ascii、utf-8、GB2312、GBK等編碼知識(shí)

    這篇文章主要介紹了趣談Unicode、Ascii、utf-8、GB2312、GBK等編碼知識(shí),文章寫的詼諧風(fēng)趣,膜拜啊,需要的朋友可以參考下
    2014-07-07
  • 調(diào)用DeepSeek?API的詳細(xì)指南

    調(diào)用DeepSeek?API的詳細(xì)指南

    章詳細(xì)介紹了如何在DeepSeek開放平臺(tái)上獲取API密鑰,并使用Apifox進(jìn)行API調(diào)試,步驟包括登錄平臺(tái)、創(chuàng)建和保存APIKey、配置Apifox環(huán)境變量、導(dǎo)入cURL并設(shè)置Authorization、發(fā)送請(qǐng)求以及根據(jù)需要修改參數(shù)實(shí)現(xiàn)對(duì)話和流式輸出,需要的朋友可以參考下
    2025-02-02
  • Flyway數(shù)據(jù)庫(kù)版本控制的教程詳解

    Flyway數(shù)據(jù)庫(kù)版本控制的教程詳解

    這篇文章主要介紹了Flyway數(shù)據(jù)庫(kù)版本控制的教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2015-07-07
  • IE條件語(yǔ)句 IE hack大全

    IE條件語(yǔ)句 IE hack大全

    條件注釋只有在IE瀏覽器被支持,因此僅適用于IE的特殊指令。從IE5起都支持
    2012-05-05
  • 利用DeepSeek實(shí)現(xiàn)復(fù)雜Git操作的詳細(xì)過程

    利用DeepSeek實(shí)現(xiàn)復(fù)雜Git操作的詳細(xì)過程

    今天綜合利用 DeepSeek V3 和 R1 推理模型,成功解決了一個(gè)復(fù)雜的 Git 操作,謹(jǐn)以此文記錄 DeepSeek 使用心得,以備后續(xù)復(fù)盤,下面是小編給大家介紹的利用DeepSeek實(shí)現(xiàn)復(fù)雜Git操作的詳細(xì)過程,需要的朋友可以參考下
    2025-02-02
  • 5個(gè)ChatGPT功能幫助你提升日常編碼效率

    5個(gè)ChatGPT功能幫助你提升日常編碼效率

    ChatGPT?作為最快完成億活用戶的應(yīng)用,最近真的是火出天際了。今天分享5個(gè)?ChatGPT?功能,來提升我們的日常工作以及如何使用它提高代碼質(zhì)量
    2023-02-02
  • git可視化工具Sourcetree使用全攻略(git沖突解決)

    git可視化工具Sourcetree使用全攻略(git沖突解決)

    本文主要介紹了git可視化工具Sourcetree使用全攻略,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • Git文件常用操作總結(jié)及拓展

    Git文件常用操作總結(jié)及拓展

    這篇文章主要為大家介紹了Git文件常用操作總結(jié)及拓展,添加多個(gè)文件到暫存區(qū),提交操作未寫備注,從工作區(qū)直接提交到版本庫(kù),有需要的朋友可以借鑒參考下
    2022-04-04

最新評(píng)論

三原县| 河源市| 襄城县| 桐柏县| 比如县| 如皋市| 库伦旗| 南华县| 阿克陶县| 延安市| 朝阳市| 黑河市| 遂平县| 丰城市| 南开区| 阿勒泰市| 遵义市| 无极县| 彩票| 鞍山市| 普安县| 措勤县| 岚皋县| 永昌县| 武威市| 江安县| 巴中市| 威海市| 红原县| 赣州市| 金湖县| 清原| 施甸县| 西贡区| 历史| 东明县| 体育| 临朐县| 安新县| 南召县| 天祝|