Tại sao một chuỗi được mã hóa base64 có dấu = ở cuối


322

Tôi biết base64mã hóa là gì và cách tính toán base64mã hóa trong C #, tuy nhiên tôi đã thấy nhiều lần rằng khi tôi chuyển đổi một chuỗi thành base64, =cuối cùng sẽ có một mã hóa.

Một vài câu hỏi được đưa ra:

  1. Có một base64chuỗi luôn kết thúc với =?
  2. Tại sao một =nhận được nối vào cuối?

9
Điều này hoàn toàn không có gì để làm với C #.
BoltClock

19
Trên thực tế, nó có liên quan đến c #, không phải tất cả các ngôn ngữ sẽ bao gồm =, ví dụ như nhiều thư viện perl bỏ qua =, vì vậy việc biết môi trường mà người dùng đang sử dụng thực sự có liên quan.
Jacob

Có vẻ như điều này làm cho nó trở thành một phương pháp che giấu kém hiệu quả hơn trong một số trường hợp vì nó khá dễ phát hiện.
dgo

6
@ user1167442 Base64 không dành cho việc xáo trộn. Nó là để vận chuyển dữ liệu nhị phân (hoặc chuỗi có unicode và các ký tự đặc biệt khác) dưới dạng chuỗi.
NH.

Câu trả lời:


270

Nó phục vụ như đệm .

Một câu trả lời đầy đủ hơn là một chuỗi được mã hóa base64 không phải lúc nào cũng kết thúc bằng một =, nó sẽ chỉ kết thúc bằng một hoặc hai =nếu chúng được yêu cầu đệm chuỗi ra theo độ dài phù hợp.


3
"Một trường hợp trong đó các ký tự đệm được yêu cầu là ghép nhiều tệp được mã hóa Base64."
André Puel

1
@ AndréPuel: resynch một người =sẽ đủ. Nếu bạn muốn tìm lại ranh giới thì một kẻ hủy diệt phải luôn luôn có mặt (và vẫn chỉ cần một char). Toàn bộ khái niệm đệm của Base64 chỉ là một bộ não ...
6502

5
Liên kết đó là hoàn toàn không liên quan đến cơ sở64, mặc dù.
NH.

1
Tôi chỉ muốn một liên kết đáng tin cậy và đáng tin cậy được đăng tải giải thích về việc đệm một base64cách hiệu quả với các minh họa và ví dụ. Liên kết hiện tại đến wikipedia hoàn toàn không liên quan như @NH. đề cập.
Fr0zenFyr

1
@ Fr0zenFyr Nếu bạn muốn có một liên kết, en.wikipedia.org/wiki/Base64#Output_padding là khá tốt. Nhưng câu trả lời của Badr thực sự là một câu hỏi hay hơn (nó vẫn chưa bắt kịp số phiếu).
NH.

313

1-Không

2- Như một câu trả lời ngắn: Ký tự thứ 65 (dấu "=") chỉ được sử dụng như một phần bổ sung trong quá trình mã hóa tin nhắn cuối cùng.

Bạn sẽ không có dấu '=' nếu chuỗi của bạn có nhiều số có 3 ký tự, bởi vì Base64mã hóa lấy mỗi ba byte (8 bit) và biểu thị chúng là bốn ký tự có thể in được trong tiêu chuẩn ASCII.

Chi tiết :

(a) Nếu bạn muốn mã hóa

ABCDEFG <=> [ ABC] [ DEF] [G

Base64sẽ đối phó (tạo ra 4 ký tự) với khối thứ nhất và khối thứ hai (khi chúng hoàn thành) nhưng đối với khối thứ ba, nó sẽ tăng gấp đôi ==trong đầu ra để hoàn thành 4 ký tự cần thiết. Vì vậy, kết quả sẽ là QUJD REVG Rw == (không có không gian)

(b) Nếu bạn muốn mã hóa ...

ABCDEFGH <=> [ ABC] [ DEF] [GH

Tương tự, nó sẽ chỉ thêm một ký tự =ở cuối đầu ra để có 4 ký tự, kết quả sẽ là QUJD REVG R0g = (không có khoảng trắng )


26
Điều này đầy đủ và rõ ràng hơn câu trả lời khác và thậm chí Wikipedia và đáng được nhiều phiếu hơn so với câu trả lời được chấp nhận, không liên quan gì đến liên kết wikipedia. Thanh danh cho bạn! Nâng cao!
ANewGuyInTown

2
@ANewGuyInTown liên kết wikipedia trong giải pháp được chấp nhận là không chính xác, nó không liên quan gì đến việc đệm trên cơ sở64. Trang đúng được liên kết bởi Legolas trong câu trả lời
Fr0zenFyr


66

Từ Wikipedia :

Chuỗi '==' cuối cùng chỉ ra rằng nhóm cuối cùng chỉ chứa một byte và '=' chỉ ra rằng nó chứa hai byte.

Vì vậy, đây là một số loại đệm.


16
  1. Không.
  2. Để đệm chuỗi được mã hóa Base64 thành nhiều ký tự có độ dài 4 ký tự, để nó có thể được giải mã chính xác.

3
Tôi đã loại bỏ phần =cuối và kiểm tra cái này cho 1 triệu chuỗi. Việc giải mã luôn khớp.
vivek_23

15

Nó được định nghĩa trong RFC 2045 là một ký tự đệm đặc biệt nếu có ít hơn 24 bit ở cuối dữ liệu được mã hóa.


11

Dấu bằng (=) được sử dụng làm phần đệm trong một số dạng mã hóa base64 nhất định. Các bài viết trên Wikipedia về base64 có tất cả các chi tiết.


2
Bạn có thể giải thích logic tại sao "==" là 1 byte và "=" là 2 byte không? Tôi không thể hiểu nó. Làm thế nào đến đầu vào: "bất kỳ niềm vui xác thịt." có thể nhận được kết quả "YW55IGNhcm5hbCBwbGVhc3VyZS4 =", trong khi "bất kỳ niềm vui xác thịt nào" có thể nhận được kết quả "YW55IGNhcm5hbCBwbGVhc3VyZQ =="?
null

14
Không phải là trường hợp đó '==' là 1 byte và '=' là 2 byte. Đó là trường hợp bạn cần luôn có nhiều 4 byte trong toàn bộ chuỗi của mình. Vì vậy, bạn đệm với dấu '=' cho đến khi bạn nhận được điều đó. Chuỗi đầu tiên có nhiều ký tự hơn chuỗi thứ hai, do đó, cần ít hơn '=' phần đệm.
Sam Holloway

2
Là câu trả lời này được cho là một nhận xét?
Fr0zenFyr

9

Đó là đệm. Từ http://en.wikipedia.org/wiki/Base64 :

Về lý thuyết, ký tự đệm không cần thiết để giải mã, vì số byte bị thiếu có thể được tính từ số chữ số Base64. Trong một số triển khai, ký tự đệm là bắt buộc, trong khi đối với những người khác, nó không được sử dụng. Một trường hợp trong đó các ký tự đệm được yêu cầu là ghép nhiều tệp được mã hóa Base64.


1
Phần về "Một trường hợp trong đó các ký tự đệm được yêu cầu là ghép nhiều tệp được mã hóa Base64." sai. Ví dụ: khi ghép hai tệp base64 trong đó các byte nguồn cho mỗi tệp dài 3 byte, chuỗi base64 sẽ dài 4 ký tự và không có byte đệm. Khi bạn nối hai chuỗi base64 này, sẽ không có cách nào để biết nơi nào bắt đầu và một chuỗi dừng dựa trên chuỗi được nối. Vì vậy, dựa vào pad64 để giúp đỡ điều đó sẽ không hiệu quả. Vấn đề này sẽ tồn tại đối với bất kỳ tệp nào có độ dài byte chia hết cho 3.
Ron C

1
Tôi đoán nó có nghĩa là trường hợp kết quả cuối cùng sẽ là sự kết hợp của các đầu vào. ví dụ decode(encode(A)+encode(B))=A+Bhoạt động với phần đệm nhưng không phải không có.
Thomas Leonard

có lẽ nhưng việc sử dụng hạn chế như vậy không cho phép các char đệm được dựa vào trong trường hợp chung là tách các chuỗi được mã hóa khi các chuỗi được mã hóa được nối với nhau. Tôi chỉ đề cập đến nó để giúp các nhà phát triển có thể nghĩ rằng họ có thể sử dụng nó theo cách đó.
Ron C

1
Tôi nghĩ rằng sự phản đối của bạn thực sự chỉ làm nổi bật sự khác biệt giữa các khái niệm về đệm và phân định. Kết quả của việc ghép nối thường không được mong đợi bao gồm đủ thông tin để làm cho nó có thể đảo ngược. Bạn sẽ không biết liệu "c3dpenpsZXJz" ban đầu là "c3dpenps" + "ZXJz" hay "c3dp" + "enpsZXJz". Nhưng bạn cũng không biết "swizzlers" ban đầu là "swi" + "zzlers" hay "swizzl" + "ers".
GargantuChet

1
Sao chép nhận xét của tôi từ câu trả lời đệm Base64 có liên quan :> Ghép Base64 [với '=' padding] cho phép các bộ mã hóa xử lý các khối lớn song song mà không phải chịu trách nhiệm sắp xếp các kích thước khối thành bội số của ba. Tương tự, như một chi tiết triển khai, có thể có một bộ mã hóa ngoài đó cần xóa bộ đệm dữ liệu nội bộ có kích thước không phải là bội số của ba.
Andre D

7

http://www.hcidata.info/base64.htm

Mã hóa "Mary had" đến Base 64

Trong ví dụ này, chúng tôi đang sử dụng một chuỗi văn bản đơn giản ("Mary had") nhưng nguyên tắc giữ cho dù dữ liệu là gì (ví dụ: tệp đồ họa). Để chuyển đổi mỗi 24 bit dữ liệu đầu vào thành 32 bit đầu ra, mã hóa Base 64 chia 24 bit thành 4 khối 6 bit. Vấn đề đầu tiên chúng tôi nhận thấy là "Mary had" không phải là bội số của 3 byte - nó dài 8 byte. Bởi vì điều này, nhóm bit cuối cùng chỉ dài 4 bit. Để khắc phục điều này, chúng tôi thêm hai bit '0' và ghi nhớ thực tế này bằng cách đặt dấu '=' ở cuối. Nếu chuỗi văn bản được chuyển đổi thành Base 64 dài 7 byte, nhóm cuối cùng sẽ có 2 bit. Trong trường hợp này, chúng tôi đã thêm bốn bit '0' và ghi nhớ thực tế này bằng cách đặt '==' ở cuối.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.