Mã hóa và giải mã Java Base64

1. Khái quát chung

Trong hướng dẫn này, chúng tôi khám phá các tiện ích khác nhau cung cấp chức năng mã hóa và giải mã Base64 trong Java.

Chúng tôi chủ yếu sẽ minh họa các API Java 8 mới và các API tiện ích sắp ra mắt từ Apache Commons.

2. Java 8 cho Cơ sở 64

Java 8 cuối cùng đã thêm khả năng Base64 vào API tiêu chuẩn. Điều này là thông qua lớp tiện ích java.util.Base64 .

Hãy bắt đầu bằng cách xem xét quy trình cơ bản của bộ mã hóa.

2.1. Java 8 cơ bản Base64

Bộ mã hóa cơ bản giúp mọi thứ đơn giản và mã hóa đầu vào như hiện tại, không có bất kỳ sự phân tách dòng nào.

Đầu ra được ánh xạ tới một bộ ký tự trong bộ ký tự A-Za-z0-9 + / và bộ giải mã từ chối bất kỳ ký tự nào bên ngoài bộ này.

Trước tiên, hãy mã hóa một chuỗi đơn giản :

String originalInput = "test input"; String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes()); 

Lưu ý cách chúng tôi truy xuất API Encoder đầy đủ thông qua phương thức tiện ích getEncoder () đơn giản .

Bây giờ hãy giải mã Chuỗi đó trở lại dạng ban đầu:

byte[] decodedBytes = Base64.getDecoder().decode(encodedString); String decodedString = new String(decodedBytes);

2.2. Mã hóa Java 8 Base64 không có đệm

Trong mã hóa Base64, độ dài của Chuỗi mã hóa đầu ra phải là bội số của ba. Nếu không, đầu ra sẽ được đệm bằng các ký tự đệm bổ sung ( = ).

Sau khi giải mã, các ký tự đệm thừa này sẽ bị loại bỏ. Để tìm hiểu sâu hơn về padding trong Base64, hãy xem câu trả lời chi tiết này trên Stack Overflow.

Nếu chúng ta cần bỏ qua phần đệm của đầu ra - có lẽ vì Chuỗi kết quả sẽ không bao giờ được giải mã trở lại - chúng tôi chỉ cần chọn mã hóa mà không có phần đệm :

String encodedString = Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());

2.3. Mã hóa URL Java 8

Mã hóa URL rất giống với bộ mã hóa cơ bản mà chúng ta đã xem xét ở trên. Nó sử dụng URL và tên tệp bảng chữ cái Safe Base64 và không thêm bất kỳ phân tách dòng nào:

String originalUrl = "//www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java"; String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes()); 

Việc giải mã diễn ra theo cùng một cách. Các getUrlDecoder () phương pháp hữu ích trả về một java.util.Base64.Decoder mà sau đó được sử dụng để giải mã các URL:

byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl); String decodedUrl = new String(decodedBytes); 

2.4. Mã hóa Java 8 MIME

Hãy bắt đầu bằng cách tạo một số đầu vào MIME cơ bản để mã hóa:

private static StringBuilder getMimeBuffer() { StringBuilder buffer = new StringBuilder(); for (int count = 0; count < 10; ++count) { buffer.append(UUID.randomUUID().toString()); } return buffer; }

Bộ mã hóa MIME tạo đầu ra được mã hóa Base64 bằng bảng chữ cái cơ bản nhưng ở định dạng thân thiện với MIME.

Mỗi dòng của đầu ra không dài hơn 76 ký tự và kết thúc bằng dấu xuống dòng theo sau là dòng cấp dữ liệu ( \ r \ n ):

StringBuilder buffer = getMimeBuffer(); byte[] encodedAsBytes = buffer.toString().getBytes(); String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);

Các getMimeDecoder () phương pháp hữu ích trả về một java.util.Base64.Decoder mà sau đó được sử dụng trong quá trình giải mã:

byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime); String decodedMime = new String(decodedBytes); 

3. Mã hóa / Giải mã bằng Apache Commons Code

Đầu tiên, chúng ta cần xác định phụ thuộc commons-codec trong pom.xml :

 commons-codec commons-codec 1.10 

Lưu ý rằng chúng tôi có thể kiểm tra xem các phiên bản mới hơn của thư viện đã được phát hành trên Maven Central hay chưa.

API chính là lớp org.apache.commons.codec.binary.Base64 , có thể được tham số hóa với các hàm tạo khác nhau:

  • Base64 (boolean urlSafe) tạo API Base64 bằng cách kiểm soát chế độ URL an toàn - bật hoặc tắt.
  • Base64 (int lineLength) tạo API Base64 ở chế độ không an toàn cho URL và kiểm soát độ dài của dòng (mặc định là 76).
  • Base64(int lineLength, byte[] lineSeparator) creates the Base64 API by accepting an extra line separator, which by default is CRLF (“\r\n”).

Once the Base64 API is created, both encoding and decoding are quite simple:

String originalInput = "test input"; Base64 base64 = new Base64(); String encodedString = new String(base64.encode(originalInput.getBytes())); 

The decode() method of Base64 class returns the decoded string:

String decodedString = new String(base64.decode(encodedString.getBytes())); 

Another simple option is using the static API of Base64instead of creating an instance:

String originalInput = "test input"; String encodedString = new String(Base64.encodeBase64(originalInput.getBytes())); String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));

4. Converting a String to a byte Array

Sometimes, we need to convert a String to a byte[]. The simplest way to do this is to use StringgetBytes() method:

String originalInput = "test input"; byte[] result = originalInput.getBytes(); assertEquals(originalInput.length(), result.length);

It's better to provide encoding as well and not depend on default encoding, as it's system dependent:

String originalInput = "test input"; byte[] result = originalInput.getBytes(StandardCharsets.UTF_16); assertTrue(originalInput.length() < result.length);

If our String is Base64 encoded, we can use the Base64 decoder:

String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = Base64.getDecoder().decode(originalInput); assertEquals("test input", new String(result));

We can also use DatatypeConverter parseBase64Binary() method:

String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = DatatypeConverter.parseBase64Binary(originalInput); assertEquals("test input", new String(result));

Finally, we can convert a hexadecimal String to a byte[] using DatatypeConverter method:

String originalInput = "7465737420696E707574"; byte[] result = DatatypeConverter.parseHexBinary(originalInput); assertEquals("test input", new String(result));

5. Conclusion

This article explained the basics of how to do Base64 encoding and decoding in Java using the new APIs introduced in Java 8 and Apache Commons.

Cuối cùng, có một số API khác đáng được đề cập cung cấp chức năng tương tự: java.xml.bind.DataTypeConverter với printHexBinaryparseBase64Binary .

Các đoạn mã có thể được tìm thấy trên GitHub.