跳至主要內容
Skip to content

從 0/1 到 0-255 — 理解 Byte 的誕生

如果你曾經好奇:「Blob 明明是二進制資料,只有 0 和 1,為什麼討論時又會冒出 0-255 這個範圍?」

這個問題觸及了計算機科學中 「編碼 (Encoding)」「資料單位」 的核心觀念。

簡單的答案是:0 和 1 實在太小了,電腦為了方便管理,把每 8 個 0/1 打包成一組,這一組就叫做「Byte (位元組)」。而這一組所能表示的數字範圍,剛好就是 0 到 255。


一、 從 Bit 到 Byte:打包的藝術

電腦底層確實只有 Bit (位元),也就是開關(0 或 1)。但如果我們傳輸資料只講 0 和 1,效率會極低且人類無法理解。

TIP

比喻 就像你去便利商店買米,你不會跟店員說:「我要 50,000 粒米」,你會說:「我要 1 包 米」。

在電腦世界裡,「1 包」的標準規格就是 8 粒米 (8 Bits)。這包米就叫做 Byte (位元組)

單位定義

單位定義範圍
1 Bit1 個開關0 或 1
1 Byte8 個 Bits 排在一起0 ~ 255

二、 數學解密:為什麼是 255?

當我們把 8 個開關排成一列,會有多少種組合?

每個位置都有 2 種可能(0 或 1),總共有 8 個位置:

$$ 2^8 = 256 \text{ 種狀態} $$

這代表一組 Byte 可以組出 256 種狀態。如果用十進位數字來表示:

  • 最小的狀態 (全都是 0):00000000 = 0
  • 最大的狀態 (全都是 1):11111111 = 255

二進位轉十進位計算

二進位的 11111111 換算成十進位是這樣加的:

位置:    7     6     5     4     3     2     1     0
權重:   128   64    32    16    8     4     2     1
值:      1     1     1     1     1     1     1     1

總和 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255

所以,0 到 255 是一個 Byte 用無符號整數表示時的數值範圍。電腦當然可以做 bit 層級操作,但在檔案、網路與 Web API 的實務中,我們最常以 Byte 為基本單位讀寫資料。


三、 Blob 與 0-255 的關係

回到主題:Blob 是一大塊二進制資料。

雖然它的本質是長長一串的 010101...,但在程式語言(JavaScript, Python, C++)眼中,它被視為一個 「由 0-255 數字組成的超長陣列」

舉個例子:一張圖片的 Blob

假設你有一個很小的紅色像素點圖片,它在 Blob 裡的樣子可能長這樣(簡化版):

記憶體位置二進位 (電腦看的)十進位 (程式碼看的)意義
Byte 111111111255紅色 (R)
Byte 2000000000綠色 (G)
Byte 3000000000藍色 (B)
Byte 411111111255透明度 (Alpha)

這就是為什麼你在 CSS 設定顏色時會看到 rgb(255, 0, 0)。在常見的 8-bit RGB/RGBA 表示法裡,每個色彩通道會用一個 Byte (0-255) 表示強度。


四、 在 JavaScript 中親眼看到它

在 Web 開發中,Blob 通常是包起來的,你看不到內容。但如果你把它「切開」變成 ArrayBuffer,再用 Uint8Array 去讀取,就會看到滿滿的 0-255。

Uint8Array 名詞解釋

  • Unsigned: 無符號(沒有負數,只有正數)
  • Int: 整數
  • 8: 8 位元 (8 bits)
  • Array: 陣列

翻譯: 「由 8 個 bit 組成的正整數陣列」,也就是 0-255 的陣列

實際操作範例

你可以試著在瀏覽器的 Console 跑這段程式碼:

javascript
// 1. 建立一個簡單的 Blob (裡面只有文字 "Hi")
const blob = new Blob(["Hi"]);

// 2. 把 Blob 轉成 ArrayBuffer (取得記憶體控制權)
blob.arrayBuffer().then((buffer) => {
  // 3. 用 "8位元視角" 去看這塊記憶體
  const view = new Uint8Array(buffer);

  console.log(view);
  // 輸出: Uint8Array(2) [72, 105]

  // 為什麼是 72 和 105?
  // 因為在 UTF-8/ASCII 中,英文字母 H 和 i 都各佔 1 byte:
  // 'H' = 72
  // 'i' = 105
  // 這些數字都在 0-255 之間!
});

TypedArray 家族

除了 Uint8Array,JavaScript 還提供其他「視角」:

類型每個元素大小數值範圍用途
Uint8Array1 Byte0 ~ 255處理原始二進位、圖片像素
Uint16Array2 Bytes0 ~ 65535音訊採樣
Uint32Array4 Bytes0 ~ 4,294,967,295大整數運算
Float32Array4 Bytes浮點數WebGL 頂點座標

如果你把 Blob 換成中文,例如 new Blob(["你好"])Uint8Array 會看到 6 個數字,因為 UTF-8 會用 3 bytes 表示一個常見中文字。這也是為什麼「文字長度」和「檔案 byte 數」經常不是同一件事。


五、 為什麼這很重要?

理解了 Blob 其實就是一堆 0-255 的數字後,你就能做到:

  1. 初步檔案驗證:透過檢查檔案開頭的數字(Magic Numbers),比副檔名更可靠地判斷檔案類型
  2. 檔案修復:有些損壞的檔案只是多了幾個錯誤的 Byte,你可以直接修正
  3. 自定義格式:你甚至可以發明自己的檔案格式,例如前 4 個 Byte 存版本號,後 4 個 Byte 存作者 ID

常見誤解

誤解正確理解
二進位資料只能看成 0 和 1底層是 bit,但程式通常用 byte 或 typed array 來看
1 個字元等於 1 byte只對部分編碼與字元成立,UTF-8 中文通常不是
Uint8Array 會複製 Blob它是用 8-bit 視角讀取 ArrayBuffer,不是直接操作原本的 Blob
0-255 是所有整數的限制這只是 1 byte 無符號整數的範圍

總結

概念說明
Bit最小單位,0 或 1,太細微難以操作
Byte8 個 Bit 綁成一組,數值範圍 0-255
Blob成千上萬個 Byte 堆疊起來的大物體
Uint8Array用 0-255 視角去讀取二進制資料的工具

當我們說 Blob 是二進制資料時,意思是它底層是 0/1;但當我們去「讀取」或「處理」它時,我們是把它當成一連串 0-255 的數字在看。


練習:猜 byte 數

練習 1:英文和中文差在哪?

先猜 byteLength 分別是多少:

javascript
const a = new Blob(["Hi"]);
const b = new Blob([""]);
const c = new Blob(["你好"]);

console.log((await a.arrayBuffer()).byteLength);
console.log((await b.arrayBuffer()).byteLength);
console.log((await c.arrayBuffer()).byteLength);
看答案

在 UTF-8 中,"Hi" 是 2 bytes,"你" 通常是 3 bytes,"你好" 通常是 6 bytes。這能驗證「字元數」不等於「byte 數」。

練習 2:親手看見 0-255

javascript
const blob = new Blob(["ABC"]);
const bytes = new Uint8Array(await blob.arrayBuffer());

console.log([...bytes]);

你應該會看到 [65, 66, 67]。接著把 "ABC" 改成 "abc",觀察數字如何變化。

自我檢查

  • 為什麼 1 byte 的最大值是 255,不是 256?
  • Uint8Array 的每個元素可以放 300 嗎?
  • 為什麼中文字的 byte 數通常比字元數多?
  • Blob 底層是 bit,但為什麼程式常用 byte 來看?

← 上一章:Blob vs Base64 | 返回專題首頁 | 下一章:互轉實戰 →