design

Base64 Encoding giải thích: Khi nào và tại sao Dev dùng (và những cạm bẫy nên tránh)

Base64 hoạt động như thế nào (3 byte thành 4 ký tự ASCII, cồng kềnh thêm 33%), các trường hợp sử dụng thực tế (data URIs, JWT, Basic auth), và những cạm bẫy: nó không phải mã hóa và cũng chẳng nén dữ liệu.

Published 2026-06-11 · 8 min read

Affiliate disclosure

Some links below are affiliate links. I may earn a commission from qualifying purchases at no extra cost to you. I only recommend tools I have used or tested.

Mọi thứ bắt đầu chỉ với HTML, CSS và một chút JavaScript.
Photo by Nangialai Stoman on Unsplash

Tóm tắt (TL;DR)

  • Base64 là một dạng mã hóa định dạng (encoding), không phải mã hóa bảo mật (encryption) và cũng không phải nén (compression). Nó viết lại các byte tùy ý thành 64 ký tự ASCII có thể in được, giúp dữ liệu nhị phân đi xuyên qua các kênh chỉ hỗ trợ văn bản.
  • Cơ chế hoạt động: cứ 3 byte lại biến thành 4 ký tự (mỗi ký tự 6 bit), được đệm bằng các dấu =, đó là lý do tại sao đầu ra luôn to hơn khoảng +33% so với đầu vào (RFC 4648, MDN).
  • Ứng dụng thực tế: data URIs (nhúng ảnh trực tiếp trong CSS/HTML), đính kèm email MIME, dữ liệu nhị phân trong JSON/XML, tiêu đề HTTP Basic auth, và các phân đoạn JWT (dùng chuẩn Base64URL).
  • Những cạm bẫy: Base64 dễ dàng bị đảo ngược (tuyệt đối không dùng thay cho lớp bảo mật), mức tăng +33% khiến nó hoàn toàn sai lầm khi dùng gửi tệp lớn qua mạng, và hàm btoa() sẽ báo lỗi với các ký tự ngoài ASCII vì nó chỉ hiểu Latin-1, không phải UTF-8.
  • Bạn có thể mã hóa/giải mã cả hai chuẩn tại công cụ Base64 của AnyTools — mọi thứ chạy ngay trên trình duyệt của bạn, không có dữ liệu nào rời khỏi thiết lập của bạn.

Bạn gặp nó mọi lúc — vậy nó là cái gì?

Bạn tình cờ thấy một chuỗi dài loằng ngoằng toàn chữ cái, chữ số và kết thúc bằng vài dấu = (chẳng hạn trong JWT, file config, data: URL, hay một header xác thực copy được), và脑子里本能地反应: ờ, Base64." Nhưng rốt cuộc nó mang lại lợi ích gì, và tại sao nó lại có mặt ở khắp nơi như vậy?

Câu trả lời ngắn gọn: Base64 viết lại dữ liệu nhị phân tùy ý chỉ bằng 64 ký tự ASCII an toàn, giúp các byte có thể đi qua các kênh chỉ hỗ trợ văn bản mà không bị hỏng. Nó không phải là một loại mật mã. Nó không hề nén dữ liệu. Nó chỉ là một lớp vận chuyển thôi. Bài viết này là bản giải thích dành cho dev: cơ chế chính xác, nơi nó thực sự phát huy tác dụng, và những nơi mọi người đang lạm dụng nó sai cách.

Rốt cuộc Base64 làm cái gì?

Base64 được quy định bởi RFC 4648. Bảng chữ cái của nó gồm 64 ký tự: A–Z, a–z, 0–9, cộng thêm +/. Một ký tự thứ 65, dấu =, chỉ được dùng để chèn thêm (padding) vào cuối.

Quá trình chuyển đổi mang tính cơ học hoàn toàn. Theo RFC 4648 §4, bộ mã hóa sẽ nhận đầu vào theo nhóm 24 bit (3 byte × 8 bit) và nhả ra 4 ký tự, mỗi ký tự đại diện cho 6 bit. Tỷ lệ 3-đổi-4 này chính là cốt lõi của câu chuyện, và nó kéo theo một hệ quả không thể tránh khỏi mà MDN đã chỉ ra: dạng mã hóa luôn to hơn khoảng một phần ba so với bản gốc — tức là mức tăng khoảng +33% (tỷ lệ 4/3). Nếu độ dài chuỗi đầu vào không chia hết cho 3, nhóm cuối cùng sẽ được đệm thêm để đầu ra là bội số của 4. Đó là lý do tại sao một số chuỗi kết thúc bằng một hoặc hai dấu =.

Một ví dụ thực tế, bạn có thể tự kiểm chứng tại công cụ Base64:

"Hi"  → 2 byte → "SGk="   (thiếu 1 byte để tạo thành nhóm 3 byte → thêm một dấu "=")
"Hello, World!" → 13 byte → "SGVsbG8sIFdvcmxkIQ=="

Từ cơ chế này, chúng ta có hai điều rút ra được, quan trọng hơn cả những phép toán:

  • Nó có thể đảo ngược hoàn toàn và không cần chìa khóa (key). Giải mã chỉ là việc tra bảng ngược lại. Không có bí mật nào can thiệp vào đây, và đây chính là nguồn gốc của hiểu lầm tai hại nhất sẽ nhắc đến bên dưới.
  • Nó đánh đổi dung lượng, không phải bảo mật. Bạn tốn ~33% dung lượng để đổi lấy sự an toàn khi vận chuyển dưới dạng văn bản: rất tuyệt vời cho một token 200 byte, nhưng lại là thảm họa cho một tệp 10 MB.

Ngoài ra còn có một "người anh em" đáng chú ý: Base64URL (RFC 4648 §5). Cùng một cách mã hóa, nhưng nó thay + bằng -/ bằng _, đồng thời thường lược bỏ luôn phần đệm = ở cuối, để đảm bảo kết quả có thể đưa thẳng vào URL, tên tệp hoặc các phân đoạn JWT mà không gặp lỗi.

Base64 thực sự tỏa sáng ở đâu?

Mọi trường hợp sử dụng Base64 hợp lý đều xoay quanh một kịch bản: dữ liệu nhị phân cần phải chen chân vào một nơi chỉ chấp nhận văn bản. Dưới đây là những nơi điều đó diễn ra trong thực tế.

  • Data URIs. Nhúng ngay một icon nhỏ trực tiếp vào CSS hoặc HTML: background: url("data:image/svg+xml;base64,PHN2Zy…"). Các byte của hình ảnh trở thành một phần của văn bản stylesheet, giúp tiết kiệm một HTTP request — nhưng chỉ đáng để dùng cho các tài nguyên dưới ~1–2 KB, bởi cái giá +33% sẽ đi theo mỗi lần trang tảiStylesheet.
  • Đính kèm Email (MIME). Đây chính là lý do Base64 ra đời. Giao thức email vốn được xây dựng cho văn bản 7-bit, nên các tệp nhị phân phải được bọc trong Base64 để tồn tại nguyên vẹn.
  • Dữ liệu nhị phân trong JSON / XML. JSON không có kiểu dữ liệu nhị phân (binary) gốc. Để nhét một đoạn blob nhỏ (như hình thu nhỏ, chữ ký số, chứng chỉ) vào trường JSON, bạn mã hóa nó bằng Base64 thành một chuỗi để bộ phân tích cú pháp có thể đọc được.
  • Xác thực HTTP Basic auth. Header Authorization: Basic … thực chất chỉ là chuỗi tên_người_dùng:mật_khẩu được mã hóa Base64. Lưu ý chữ mã hóa định dạng: Basic auth tự nó mang lại độ bảo mật bằng 0 và hoàn toàn phụ thuộc vào HTTPS. Base64 ở đây chỉ là cách đóng gói khuôn mẫu, chứ không phải lớp bảo vệ.
  • Các phân đoạn JWT. Một JSON Web Token có dạng header.payload.signature, trong đó mỗi phần là các đối tượng JSON được mã hóa bằng Base64URL. Bạn hoàn toàn có thể copy đoạn ở giữa bỏ vào trình giải mã và đọc được mọi Claim trong đó, đó là lý do bạn tuyệt đối không được lưu các thông tin bí mật trong payload của JWT.

Đối với các trường hợp liên quan đến URL, Base64 thường đi kèm với một kiểu mã hóa khác. Nếu bạn đang tự tay lắp ráp một URL mang theo một giá trị đã được Base64, các ký tự +, /, và = vẫn cần được chuyển đổi cho thân thiện với URL: hoặc dùng Base64URL ngay từ đầu, hoặc đưa URL qua mã hóa phần trăm (percent-encoding) để các ký tự đó sống sót qua chuỗi truy vấn. Và khi bạn cần một mã định danh văn bản (text identifier) duy nhất thay vì các byte được mã hóa, trình tạo UUID mới là công cụ phù hợp — UUID là mã định danh, không phải để mã hóa payload.

Khi nào KHÔNG nên dùng Base64?

Đây là phần quan trọng nhất. Base64 bị lạm dụng chính ở ba trường hợp sau, và mỗi trường hợp đều là một lỗi (bug) chực chờ xảy ra.

1. Nó là mã hóa định dạng (encoding), không phải mã hóa bảo mật (encryption), nên đừng bao giờ dùng cho mục đích an toàn. Đây là tội lỗi chí mạng. Base64 không có chìa khóa (key); bất kỳ ai cũng có thể đảo ngược nó trong một bước. Một mật khẩu, API key, hay token được "lưu trữ dưới dạng Base64" thì chẳng khác gì lưu dưới dạng văn bản rõ (plaintext); việc mã hóa chỉ thay đổi diện mạo của các ký tự mà thôi, như MDN đã lưu ý. Nếu cần tính bảo mật, hãy mã hóa (encrypt). Nếu cần lưu trữ thông tin xác thực, hãy băm (hash) chúng bằng bcrypt, scrypt, hoặc argon2.

2. Nó là công cụ sai lầm khi dùng gửi tệp lớn qua mạng. Vì phải gánh mức tăng kích thước cứng nhắc +33%, việc mã hóa Base64 một bức ảnh lớn hay gửi tệp hàng megabyte dưới dạng chuỗi JSON sẽ lãng phí băng thông và ép hệ thống phải giải mã toàn bộ trong bộ nhớ cùng lúc. Đối với những thứ vượt quá tài nguyên nhỏ, hãy gửi nhị phân đúng chuẩn (dùng multipart/form-data, hoặc HTTP body nhị phân) và tham chiếu bằng URL. Data URI nội tuyến chỉ dành cho các tài nguyên cỡ favicon, chứ không phải ảnh bìa (hero image).

3. Nó không phải là nén dữ liệu (compression). Base64 làm dữ liệu to ra, chứ không bao giờ làm nó nhỏ đi. Để nén payload, bạn cần gzip/brotli. Đôi khi mọi người Base64 một đoạn blob "cho dễ di chuyển" và kết quả là tự làm nó phình to thêm.

Dưới đây là bảng quyết định nhanh.

Tình huốngCó dùng Base64?Lý do
Icon nhúng trong CSS/HTML, dưới ~1–2 KB✅ CóTiết kiệm HTTP request; mức +33% là quá nhỏ ở cỡ này
Tài nguyên lớn hơn vài KB🚫 KhôngMức +33% nhúng vào mọi trang sẽ thiệt hại nhiều hơn cái request được tiết kiệm; hãy dùng request tệp thông thường
Đoạn blob nhị phân trong trường JSON/XML✅ CóJSON không có kiểu nhị phân; văn bản là lựa chọn duy nhất
Giá trị đưa vào URL hoặc JWT✅ Có — Base64URLCác ký tự + / = không an toàn trong URL; bảng chữ cái URL-safe sẽ khắc phục điều đó
Lưu mật khẩu hoặc API key🚫 KhôngCó thể đảo ngược — tức là plaintext. Hãy băm hoặc mã hóa bảo mật thay thế
Gửi ảnh 5 MB lên server🚫 KhôngTiêu tốn thêm +33%; hãy dùng upload nhị phân thực thụ và một URL
Muốn thu nhỏ payload🚫 KhôngBase64 làm phình to dữ liệu; hãy dùng gzip/brotli

Và đây là một bảng tham khảo nhanh cho các loại mã hóa hay bị nhầm lẫn với nhau:

Loại mã hóaBảng chữ cái / DạngĐược thiết kế cho
Base64A–Z a–z 0–9 + /, đệm =Nhị phân → Văn bản ASCII (email, JSON, data URIs)
Base64URL+-, /_, không đệmNhị phân → văn bản an toàn khi nằm trong URL / tên tệp / JWT
Mã hóa URL (percent encoding)%XX cho các ký tự không an toànBiến văn bản thành dạng an toàn trong URL — một bài toán khác hẳn
Hex0–9 a–f, 2 ký tự/byteByte dễ đọc; tăng kích thước +100%, đơn giản hơn Base64

Làm thế nào để mã hóa và giải mã đúng cách?

Bạn có thể làm điều này ngay trên trình duyệt mà không cần cài đặt npm package.

  1. Mở công cụ Base64 của AnyTools. Nó chạy hoàn toàn ở phía client — dữ liệu đầu vào của bạn không bao giờ rời khỏi thiết bị.
  2. Mã hóa: dán văn bản hoặc byte, lấy chuỗi Base64. Bật chế độ URL-safe nếu giá trị sẽ được đưa vào URL, tên tệp, hoặc JWT — bạn sẽ nhận được -/_ và không có đệm =.
  3. Giải mã: dán chuỗi Base64 (hoặc Base64URL) để khôi phục bản gốc. Công cụ sẽ tự động nhận diện chuẩn đang dùng, nên bạn không cần phải tự đoán xem đó là chuẩn nào.
  4. Các ký tự ngoài ASCII hoạt động hoàn hảo. Công cụ sẽ mã hóa UTF-8 trước, nên emoji, tiếng Latin có dấu, tiếng Việt, tiếng Ả Rập đều được giữ nguyên vẹn khi mã hóa và giải mã — sẽ không có lỗi InvalidCharacterError của btoa() phát sinh khi bạn dùng 世界 hay 🌏.

Nếu bạn đang thao tác trong code, các hàm btoa()/atob() gốc của trình duyệt chỉ nói tiếng Latin-1 chứ không phải UTF-8. Do đó, hãy bọc chúng trong TextEncoder/TextDecoder cho bất kỳ ký tự nào nằm ngoài ASCII cơ bản, theo tài liệu của MDN.

Tóm lại

Base64 là một trong những công cụ nhàm chán nhưng hữu ích nhất trong hệ sinh thái dev, và hầu hết mọi vấn đề liên quan đến nó đều xuất phát từ việc chúng ta quên mất bản chất của nó. Nó là một cách mã hóa để vận chuyển: biến byte ngẫu nhiên thành 64 ký tự ASCII an toàn với cái giá cố định là +33% kích thước, giúp dữ liệu nhị phân đi qua các kênh chỉ hỗ trợ văn bản như email, JSON, URL, và headers. Hãy dùng nó cho data URIs, MIME, blob trong JSON, Basic auth, và JWT (biến thể URL-safe). Tuyệt đối không dùng nó thay cho bảo mật (vì không có key và dễ đảo ngược), gửi tệp lớn qua mạng (băng thông sẽ đội lên), hay để nén dữ liệu (nó chỉ làm dữ liệu phình to thêm).

Hãy khắc cốt ghi tâm một câu: mã hóa vận chuyển, không phải két sắt và cũng chẳng phải máy nén, và bạn sẽ luôn dùng nó đúng lúc. Hãy dùng công cụ Base64 khi bạn cần đọc claim của JWT, nhúng một icon dưới 2 KB, hoặc kiểm tra nhanh một giá trị đã mã hóa; nhưng hãy chuyển sang upload nhị phân (multipart/form-data) ngay khi tài nguyên vượt quá vài KB. Công cụ chạy ngay trên trình duyệt của bạn, hỗ trợ cả hai chuẩn — văn bản bạn dán vào sẽ không bao giờ bị gửi tới máy chủ.

Lộ ý: bài viết này có thể chứa liên kết tiếp thị liên kết; anytools có thể nhận được hoa hồng mà không tốn thêm bất kỳ chi phí nào cho bạn.

Nguồn

  1. IETF: RFC 4648 — The Base16, Base32, and Base64 Data Encodings
  2. IETF: RFC 4648 §5 — Base64 URL- and filename-safe alphabet
  3. MDN: Base64 (Glossary) — encoding, 6 bits per digit, ~33% size increase
  4. MDN: Window.btoa() — Base64 encoding in the browser
  5. MDN: Window.atob() — Base64 decoding in the browser
  6. IETF: RFC 7519 — JSON Web Token (JWT), Base64URL-encoded segments

Đọc tiếp


“Nói suông thì rẻ. Cho tôi xem code.”
― Linus Torvalds

design

Bảng Tham Khảo Cú Pháp Cron (2026): Đọc và Tạo Mọi Biểu Thức Crontab

Giải thích cú pháp cron: thứ tự 5 trường, mô hình đọc trong 10 giây, 16 biểu thức đã kiểm chứng, cái bẫy OR của ngày trong tuần, các lỗi DST và so sánh cron với systemd timers.

10 min read

công cụ kiểm regex và tạo pattern cho developer — hình minh họa hero gốc

design

Regex Tester & Pattern Builder: Hướng Dẫn Thực Hành Viết Regex Xịn Xò, Chạy Chuẩn

Cách viết regex thực sự hiệu quả: từ anchor, quantifier, cái bẫy khác biệt giữa các engine, đến lỗi ReDoS có thể làm sập server của bạn. Hãy luôn test khi viết.

9 min read

Laptop mở code và cây cảnh nhỏ trong quán cà phê

design

JSON vs YAML vs TOML: Khi Nào Nên Chọn Định Dạng Nào (Cẩm Nang Quyết Định cho Developer)

So sánh JSON vs YAML vs TOML: Chọn JSON cho API và data, YAML cho config Kubernetes/CI (cẩn thận 'Norway problem'), TOML cho config tường minh như Cargo.toml. Cẩm nang quyết định rõ ràng.

9 min read

Một mã QR có thể quét trên nền xanh lá, minh họa cho thiết kế mã QR mang thương hiệu riêng

design

Mã QR Mang Thương Hiệu Riêng: Thêm Logo và Màu Sắc Với Công Cụ Tạo Mã QR Miễn Phí

Cách cơ chế sửa lỗi cho phép bạn chèn logo lên mã QR, các quy tắc về độ tương phản và vùng yên tĩnh để mã vẫn quét được, và sự thật về mã QR tĩnh so với động.

8 min read

Các thẻ màu Swatchos hiển thị giá trị CMYK và HEX RGB đang được sử dụng bởi một đồ họa trên bàn làm việc của họ

design

HEX sang RGB sang CMYK năm 2026: Tại sao màu in luôn khác màu trên màn hình

Đổi HEX sang RGB là phép toán chính xác tuyệt đối. Nhưng RGB sang CMYK lại là một phép 'đoán mò' có sự hao hụt, phụ thuộc vào máy in, chất liệu giấy và hồ sơ màu ICC. Đây là sự khác biệt, các phép toán thực tế, và lúc nào thì công cụ chuyển đổi trực tuyến thực sự hữu ích.

8 min read

Cận cảnh tờ sticker sheet Google Material design trên MacBook.

design

Công cụ bảng màu trợ năng: Vì sao hầu hết bảng màu thất bại trước khi bạn tung ra

83.6% trang chủ không đạt tiêu chuẩn tương phản. Cách chọn công cụ kiểm chứng bảng màu trợ năng, tránh sai lầm phổ biến và kiểm tra đúng tổ hợp màu.

9 min read