Base64
7 công cụ
Mã hóa là gì?
Mã hóa là quá trình chuyển đổi dữ liệu từ dạng biểu diễn này sang dạng khác. Trong phát triển web, mã hóa được dùng để truyền dữ liệu an toàn qua các kênh được thiết kế cho bộ ký tự hạn chế — ví dụ: gửi dữ liệu nhị phân qua giao thức dựa trên văn bản, hoặc đưa ký tự đặc biệt vào URL.
Mã hóa ký tự xác định cách các ký tự văn bản ánh xạ sang byte. Base64 chuyển đổi dữ liệu nhị phân thành văn bản ASCII. Mã hóa URL làm cho văn bản bất kỳ an toàn để sử dụng trong URL. Hiểu ba tầng mã hóa này giúp ngăn ngừa các lỗi tinh vi và lỗ hổng bảo mật.
Lịch sử mã hóa ký tự
Mã hóa ký tự là sự ánh xạ giữa các ký tự (chữ cái, ký hiệu) và biểu diễn nhị phân của chúng. Sự tiến hóa từ ASCII sang Unicode phản ánh quá trình toàn cầu hóa của web:
Mã chuẩn Mỹ 7 bit. 128 ký tự: chữ cái tiếng Anh, chữ số, dấu câu và mã điều khiển. Xác định nền tảng mã hóa mà tất cả các chuẩn khác đều mở rộng từ đó.
ASCII mở rộng cho các ngôn ngữ Tây Âu. Thêm 128 ký tự (chữ có dấu, ký hiệu). Không phù hợp với các ký tự phi Latin.
Bộ ký tự toàn cầu bao phủ tất cả hệ thống chữ viết trên thế giới. Định nghĩa điểm mã cho hơn 149.000 ký tự trong 161 hệ thống chữ viết. Không định nghĩa mã hóa — đó là nhiệm vụ của UTF-8/16/32.
Mã hóa Unicode có độ rộng thay đổi, dùng 1–4 byte mỗi ký tự. Tương thích với ASCII (128 điểm mã đầu tiên là byte đơn). Mã hóa phổ biến nhất trên web — hơn 98% trang web sử dụng.
Mã hóa có độ rộng thay đổi, dùng 2 hoặc 4 byte mỗi ký tự. Được sử dụng nội bộ bởi Windows, Java và chuỗi JavaScript. Không tương thích với ASCII.
Mã hóa có độ rộng cố định: luôn dùng 4 byte mỗi ký tự. Đơn giản nhưng tốn bộ nhớ. Dùng trong một số cơ sở dữ liệu nội bộ. Hiếm gặp trên web.
Tại sao UTF-8 thắng thế
UTF-8 trở nên phổ biến vì nó tương thích ngược với ASCII (128 ký tự đầu tiên được mã hóa giống nhau), tự đồng bộ hóa (có thể tìm ranh giới ký tự bằng cách quét), và tiết kiệm không gian cho văn bản Latin. Bất kỳ tài liệu ASCII nào cũng là tài liệu UTF-8 hợp lệ. Điều này giúp việc di chuyển trở nên liền mạch.
Mã hóa Base64
Base64 chuyển đổi dữ liệu nhị phân thành dạng văn bản chỉ sử dụng 64 ký tự ASCII có thể in được: A-Z, a-z, 0-9, + và /. Điều này cần thiết khi dữ liệu nhị phân phải truyền qua các kênh chỉ xử lý văn bản — tệp đính kèm email, data URI, JWT token và HTTP Basic Auth đều dùng Base64.
Cách hoạt động
Base64 nhóm các byte đầu vào thành các khối 3 byte (24 bit) và mã hóa mỗi khối thành 4 ký tự Base64 (6 bit mỗi ký tự). Nếu đầu vào không phải bội số của 3 byte, ký tự đệm = sẽ được thêm vào để hoàn chỉnh nhóm cuối:
| Đầu vào | Byte hex | Base64 |
|---|---|---|
| "Man" | 77 61 6E | TWFu |
| "Ma" | 4D 61 | TWE= |
| "M" | 4D | TQ== |
Các ký tự đệm = ở cuối cho biết có bao nhiêu byte còn thiếu để hoàn chỉnh nhóm 3 byte cuối. Một = nghĩa là cần thêm 1 byte đệm; == nghĩa là cần thêm 2 byte. Base64 chuẩn luôn tạo ra đầu ra có độ dài là bội số của 4.
Mã hóa URL
URL chỉ có thể chứa một tập hợp giới hạn các ký tự ASCII an toàn. Bất kỳ ký tự nào nằm ngoài tập hợp đó — bao gồm dấu cách, dấu câu, ký tự non-ASCII và các ký tự URL đặc biệt như &, = và # — phải được mã hóa phần trăm (URL encoding) trước khi đặt vào URL.
Mã hóa phần trăm thay thế mỗi byte không an toàn bằng ký tự % theo sau là hai chữ số thập lục phân biểu diễn giá trị byte đó. Dấu cách trở thành %20, dấu và trở thành %26, và tương tự.
Các ký tự thường được mã hóa
| Ký tự | Đã mã hóa | Ghi chú |
|---|---|---|
| Space | %20 | Phổ biến nhất; dùng trong form submission dưới dạng + trong application/x-www-form-urlencoded |
| & | %26 | Ký tự phân tách query string; phải mã hóa khi dùng làm giá trị chuỗi |
| = | %3D | Ký tự phân tách key-value trong query string; mã hóa khi dùng làm dữ liệu |
| + | %2B | Được hiểu là dấu cách trong application/x-www-form-urlencoded; mã hóa để giữ nguyên ký tự + thực |
| # | %23 | Định danh fragment; mã hóa khi dùng làm dữ liệu chuỗi trong đường dẫn hoặc query |
| / | %2F | Ký tự phân tách đoạn đường dẫn; mã hóa khi dùng làm dữ liệu chuỗi, không phải dấu phân cách đường dẫn |
| : | %3A | Ký tự phân tách scheme; mã hóa trong ngữ cảnh đường dẫn và query |
| @ | %40 | Dùng trong mailto: và xác thực; mã hóa khi dùng làm dữ liệu chuỗi |
encodeURI vs encodeURIComponent
JavaScript cung cấp hai hàm mã hóa với phạm vi khác nhau. encodeURI mã hóa toàn bộ URL — nó giữ nguyên các ký tự có ý nghĩa trong URL (:, /, ?, #, @). encodeURIComponent mã hóa một thành phần URL (giá trị tham số query hoặc đoạn đường dẫn) — nó mã hóa tất cả ký tự ngoại trừ A-Z, a-z, 0-9, -, _, ., ~. Luôn dùng encodeURIComponent cho từng giá trị riêng lẻ và encodeURI cho URL đầy đủ.
Mã hóa xuất hiện ở đâu trong phát triển web
Header Authorization: Basic mã hóa thông tin xác thực dưới dạng Base64(username:password). Đây là mã hóa phục vụ truyền tải, KHÔNG phải bảo mật — Base64 có thể giải mã dễ dàng. Luôn dùng HTTPS kết hợp với Basic Auth.
Data URI nhúng nội dung tệp trực tiếp vào HTML hoặc CSS: data:image/png;base64,.... Mã hóa Base64 ảnh và phông chữ nội tuyến giúp loại bỏ các yêu cầu HTTP, nhưng tăng kích thước tài liệu (~33% chi phí bổ sung).
Email được thiết kế cho ASCII 7 bit. Các tệp đính kèm nhị phân (ảnh, PDF) được MIME mã hóa Base64 trước khi truyền. Ứng dụng email của bạn sẽ tự động giải mã khi hiển thị email.
JWT token sử dụng mã hóa Base64url (biến thể thay + bằng - và / bằng _, không có ký tự đệm) cho cả ba phần (header, payload, signature). Điều này giúp token an toàn khi dùng trong URL mà không cần mã hóa phần trăm thêm.
Mọi dữ liệu người dùng nhập trong query string của URL đều phải được mã hóa phần trăm. Nếu không mã hóa & hoặc = trong một giá trị, quá trình phân tích query string sẽ bị lỗi âm thầm. Luôn dùng encodeURIComponent cho từng giá trị riêng lẻ.
Tên miền không phải ASCII (ví dụ: münchen.de) được mã hóa bằng Punycode (tiền tố xn--) để tương thích với hệ thống DNS. Trình duyệt hiển thị dạng Unicode nhưng gửi dạng Punycode đến trình phân giải DNS.
Câu hỏi thường gặp
Không. Base64 là mã hóa dữ liệu, không phải mã hóa bảo mật. Đây là phép biến đổi có thể đảo ngược, không có khóa bí mật. Bất kỳ ai nhìn thấy chuỗi Base64 đều có thể giải mã ngay lập tức. Không bao giờ dùng Base64 như một biện pháp bảo mật.
Base64 xử lý đầu vào theo nhóm 3 byte. Nếu đầu vào không phải bội số của 3 byte, ký tự đệm = sẽ được thêm vào để hoàn chỉnh nhóm cuối. Một = nghĩa là cần thêm 1 byte đệm; == nghĩa là cần thêm 2 byte. Một số triển khai bỏ qua ký tự đệm (Base64url dùng cho JWT).
Base64url là biến thể an toàn cho URL của Base64, thay + bằng - và / bằng _, thường bỏ qua ký tự đệm =. Điều này cho phép dùng trong URL và HTTP header mà không cần mã hóa phần trăm. JWT dùng Base64url cho cả ba phần.
Dùng encodeURIComponent cho từng giá trị riêng lẻ (giá trị tham số query, giá trị đoạn đường dẫn). Dùng encodeURI cho chuỗi URL đầy đủ khi muốn giữ nguyên các ký tự cấu trúc URL (/, :, ?, #). Khi không chắc, hãy dùng encodeURIComponent.
UTF-8 tương thích với ASCII và tiết kiệm không gian cho văn bản Latin (hầu hết URL, thẻ HTML và code là ASCII). UTF-16 tốn bộ nhớ hơn cho nội dung ASCII và không tương thích ngược. HTTP và HTML mặc định dùng UTF-8.
Mã hóa phần trăm (URL encoding) biểu diễn ký tự bằng % theo sau là giá trị byte thập lục phân hai chữ số. Ví dụ: dấu cách là %20 (thập phân 32, hex 20). Các ký tự UTF-8 nhiều byte sẽ mã hóa từng byte riêng: é là %C3%A9.
Base64 tăng kích thước dữ liệu khoảng 33% và tốn thêm CPU để mã hóa/giải mã. Với các hệ thống có thông lượng cao, nên ưu tiên giao thức nhị phân. Mã hóa URL tốn ít chi phí hơn nhưng có thể làm URL dài hơn đáng kể khi có nhiều ký tự đặc biệt.
Punycode là mã hóa để biểu diễn các ký tự Unicode trong hệ thống DNS tương thích ASCII. Tên miền quốc tế hóa như münchen.de được mã hóa thành xn--mnchen-3ya.de trong truy vấn DNS. Trình duyệt hiển thị dạng Unicode nhưng dùng Punycode nội bộ.