[英]Encoding as Base64 in Java
我需要在 Java 中对 Base64 编码中的一些数据进行编码。 我怎么做? 提供 Base64 编码器的 class 的名称是什么?
我尝试使用sun.misc.BASE64Encoder
class,但没有成功。 我有以下 Java 7 代码行:
wr.write(new sun.misc.BASE64Encoder().encode(buf));
我正在使用 Eclipse。 Eclipse 将此行标记为错误。 我导入了所需的库:
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
但同样,它们都显示为错误。 我在这里找到了类似的帖子。
我使用 Apache Commons 作为建议的解决方案,包括:
import org.apache.commons.*;
并导入从以下位置下载的 JAR 文件: http://commons.apache.org/codec/
但问题仍然存在。 Eclipse 仍然显示前面提到的错误。 我应该怎么办?
您需要更改 class 的导入:
import org.apache.commons.codec.binary.Base64;
然后将您的 class 更改为使用 Base64 class。
这是一些示例代码:
byte[] encodedBytes = Base64.encodeBase64("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
然后阅读为什么不应该使用 sun.* packages 。
您现在可以将java.util.Base64
与 Java 8 一起使用。首先,像往常一样导入它:
import java.util.Base64;
然后使用 Base64 static 方法如下:
byte[] encodedBytes = Base64.getEncoder().encode("Test".getBytes());
System.out.println("encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.getDecoder().decode(encodedBytes);
System.out.println("decodedBytes " + new String(decodedBytes));
如果您直接想对字符串进行编码并将结果作为编码字符串获取,则可以使用:
String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());
有关更多信息,请参阅Base64 的 Java 文档。
使用 Java 8 永远不会太晚加入有趣的 class: java.util.Base64
new String(Base64.getEncoder().encode(bytes));
在 Java 8 中可以这样完成: Base64.getEncoder().encodeToString(string.getBytes(StandardCharsets.UTF_8))
这是一个简短的、独立的完整示例:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Temp {
public static void main(String... args) throws Exception {
final String s = "old crow medicine show";
final byte[] authBytes = s.getBytes(StandardCharsets.UTF_8);
final String encoded = Base64.getEncoder().encodeToString(authBytes);
System.out.println(s + " => " + encoded);
}
}
Output:
old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==
您还可以使用 Base64 编码进行转换。 为此,您可以使用javax.xml.bind.DatatypeConverter#printBase64Binary
方法。
例如:
byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));
与番石榴
pom.xml:
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>14.0.1</version>
</dependency>
示例代码:
// encode
String s = "Hello Việt Nam";
String base64 = BaseEncoding.base64().encode(s.getBytes("UTF-8"));
// decode
System.out.println("Base64:" + base64); // SGVsbG8gVmnhu4d0IE5hbQ==
byte[] bytes = BaseEncoding.base64().decode(base64);
System.out.println("Decoded: " + new String(bytes, "UTF-8")); // Hello Việt Nam
Eclipse 给您一个错误/警告,因为您正在尝试使用特定于 JDK 供应商的内部类,而不是公共 API 的一部分。 Jakarta Commons 提供了自己的 base64 编解码器实现,它们当然驻留在不同的 package 中。 删除这些导入并让 Eclipse 为您导入正确的 Commons 类。
对于Java 6 -7,最好的选择是从 Android 存储库中借用代码。 它没有依赖关系。
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java
Java 8 确实包含自己的Base64实现。 但是,我发现了一个稍微令人不安的差异。 为了说明,我将提供一个代码示例:
我的编解码器包装器:
public interface MyCodec
{
static String apacheDecode(String encodedStr)
{
return new String(Base64.decodeBase64(encodedStr), Charset.forName("UTF-8"));
}
static String apacheEncode(String decodedStr)
{
byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
return Base64.encodeBase64String(decodedByteArr);
}
static String javaDecode(String encodedStr)
{
return new String(java.util.Base64.getDecoder().decode(encodedStr), Charset.forName("UTF-8"));
}
static String javaEncode(String decodedStr)
{
byte[] decodedByteArr = decodedStr.getBytes(Charset.forName("UTF-8"));
return java.util.Base64.getEncoder().encodeToString(decodedByteArr);
}
}
测试 Class:
public class CodecDemo
{
public static void main(String[] args)
{
String decodedText = "Hello World!";
String encodedApacheText = MyCodec.apacheEncode(decodedText);
String encodedJavaText = MyCodec.javaEncode(decodedText);
System.out.println("Apache encoded text: " + MyCodec.apacheEncode(encodedApacheText));
System.out.println("Java encoded text: " + MyCodec.javaEncode(encodedJavaText));
System.out.println("Encoded results equal: " + encodedApacheText.equals(encodedJavaText));
System.out.println("Apache decode Java: " + MyCodec.apacheDecode(encodedJavaText));
System.out.println("Java decode Java: " + MyCodec.javaDecode(encodedJavaText));
System.out.println("Apache decode Apache: " + MyCodec.apacheDecode(encodedApacheText));
System.out.println("Java decode Apache: " + MyCodec.javaDecode(encodedApacheText));
}
}
OUTPUT:
Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA0K
Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: false
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Exception in thread "main" java.lang.IllegalArgumentException: Illegal base64 character d
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
at java.util.Base64$Decoder.decode(Base64.java:549)
请注意,Apache 编码文本的末尾包含额外的换行符(空格)。 因此,为了让我的编解码器无论 Base64 实现如何都能产生相同的结果,我必须在 Apache 编码文本上调用trim()
。 就我而言,我只是将上述方法调用添加到我的编解码器的apacheDecode()
中,如下所示:
return Base64.encodeBase64String(decodedByteArr).trim();
进行此更改后,结果将是我期望的开始:
Apache encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Java encoded text: U0dWc2JHOGdWMjl5YkdRaA==
Encoded results equal: true
Apache decode Java: Hello World!
Java decode Java: Hello World!
Apache decode Apache: Hello World!
Java decode Apache: Hello World!
结论:如果您想从 Apache Base64 切换到 Java,您必须:
如果您在不遵循这些步骤的情况下进行切换,您很可能会遇到问题。 这就是我做出这个发现的原因。
要进行转换,您需要从Base64Coder 获得的编码器和解码器 - Java 中的开源 Base64 编码器/解码器。 这是您需要的文件Base64Coder.java 。
现在要根据您的要求访问此 class,您将需要以下 class:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Base64 {
public static void main(String args[]) throws IOException {
/*
* if (args.length != 2) {
* System.out.println(
* "Command line parameters: inputFileName outputFileName");
* System.exit(9);
* } encodeFile(args[0], args[1]);
*/
File sourceImage = new File("back3.png");
File sourceImage64 = new File("back3.txt");
File destImage = new File("back4.png");
encodeFile(sourceImage, sourceImage64);
decodeFile(sourceImage64, destImage);
}
private static void encodeFile(File inputFile, File outputFile) throws IOException {
BufferedInputStream in = null;
BufferedWriter out = null;
try {
in = new BufferedInputStream(new FileInputStream(inputFile));
out = new BufferedWriter(new FileWriter(outputFile));
encodeStream(in, out);
out.flush();
}
finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
private static void encodeStream(InputStream in, BufferedWriter out) throws IOException {
int lineLength = 72;
byte[] buf = new byte[lineLength / 4 * 3];
while (true) {
int len = in.read(buf);
if (len <= 0)
break;
out.write(Base64Coder.encode(buf, 0, len));
out.newLine();
}
}
static String encodeArray(byte[] in) throws IOException {
StringBuffer out = new StringBuffer();
out.append(Base64Coder.encode(in, 0, in.length));
return out.toString();
}
static byte[] decodeArray(String in) throws IOException {
byte[] buf = Base64Coder.decodeLines(in);
return buf;
}
private static void decodeFile(File inputFile, File outputFile) throws IOException {
BufferedReader in = null;
BufferedOutputStream out = null;
try {
in = new BufferedReader(new FileReader(inputFile));
out = new BufferedOutputStream(new FileOutputStream(outputFile));
decodeStream(in, out);
out.flush();
}
finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
}
private static void decodeStream(BufferedReader in, OutputStream out) throws IOException {
while (true) {
String s = in.readLine();
if (s == null)
break;
byte[] buf = Base64Coder.decodeLines(s);
out.write(buf);
}
}
}
在 Android 中,您可以将 bitmap 转换为 Base64 以上传到服务器或 Z2567A5EC9705EB7AC2C984033E016 服务。
Bitmap bmImage = //Data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageData = baos.toByteArray();
String encodedImage = Base64.encodeArray(imageData);
这个“encodedImage”是图像的文本表示。 您可以将其用于上传目的或直接显示到 HTML 页面,如下所示(参考):
<img alt="" src="data:image/png;base64,<?php echo $encodedImage; ?>" width="100px" />
<img alt="" src="data:image/png;base64,/9j/4AAQ...........1f/9k=" width="100px" />
On Android, use the static methods of the android.util.Base64 utility class. 引用的文档说 Base64 class 已添加到 API 级别 8( Android 2.2 (Froyo))中。
import android.util.Base64;
byte[] encodedBytes = Base64.encode("Test".getBytes());
Log.d("tag", "encodedBytes " + new String(encodedBytes));
byte[] decodedBytes = Base64.decode(encodedBytes);
Log.d("tag", "decodedBytes " + new String(decodedBytes));
Apache Commons有一个很好的 Base64 实现。 您可以这样做:
// Encrypt data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(str .getBytes());
System.out.println("ecncoded value is " + new String(bytesEncoded));
// Decrypt data on other side, by processing encoded data
byte[] valueDecoded= Base64.decodeBase64(bytesEncoded );
System.out.println("Decoded value is " + new String(valueDecoded));
您可以在使用 Java 和 Z686155AF75A60A0F6E9D80C1 的 Base64编码中找到有关 base64 编码的更多详细信息。
如果您使用Spring Framework至少版本 4.1,您可以使用org.springframework.util.Base64Utils class:
byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);
It will delegate to Java 8's Base64, Apache Commons Codec, or JAXB DatatypeConverter, depending on what is available.
在 Java 7 我编码了这个方法
import javax.xml.bind.DatatypeConverter;
public static String toBase64(String data) {
return DatatypeConverter.printBase64Binary(data.getBytes());
}
Java 8 的简单示例:
import java.util.Base64;
String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
If you are stuck to an earlier version of Java than 8 but already using AWS SDK for Java , you can use com.amazonaws.util.Base64 .
我尝试使用以下代码片段。 它运作良好。:-)
com.sun.org.apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");
public String convertImageToBase64(String filePath) {
byte[] fileContent = new byte[0];
String base64encoded = null;
try {
fileContent = FileUtils.readFileToByteArray(new File(filePath));
} catch (IOException e) {
log.error("Error reading file: {}", filePath);
}
try {
base64encoded = Base64.getEncoder().encodeToString(fileContent);
} catch (Exception e) {
log.error("Error encoding the image to base64", e);
}
return base64encoded;
}
将此库添加到您的应用级别依赖项中
实施 'org.apache.commons:commons-collections4:4.4'
Base64
格式的字符串长度大于原始字符串的长度:平均为133%
。 所以首先用GZIP
压缩它,然后编码为Base64
是有意义的。 对于超过 200 个字符或更多字符的字符串,它最多可减少77%
。 例子:
public static void main(String[] args) throws IOException {
byte[] original = randomString(100).getBytes(StandardCharsets.UTF_8);
byte[] base64 = encodeToBase64(original);
byte[] gzipToBase64 = encodeToBase64(encodeToGZIP(original));
byte[] fromBase64 = decodeFromBase64(base64);
byte[] fromBase64Gzip = decodeFromGZIP(decodeFromBase64(gzipToBase64));
// test
System.out.println("Original: " + original.length + " bytes, 100%");
System.out.println("Base64: " + base64.length + " bytes, "
+ (base64.length * 100 / original.length) + "%");
System.out.println("GZIP+Base64: " + gzipToBase64.length + " bytes, "
+ (gzipToBase64.length * 100 / original.length) + "%");
//Original: 3700 bytes, 100%
//Base64: 4936 bytes, 133%
//GZIP+Base64: 2868 bytes, 77%
System.out.println(Arrays.equals(original, fromBase64)); // true
System.out.println(Arrays.equals(original, fromBase64Gzip)); // true
}
public static byte[] decodeFromBase64(byte[] arr) {
return Base64.getDecoder().decode(arr);
}
public static byte[] encodeToBase64(byte[] arr) {
return Base64.getEncoder().encode(arr);
}
public static byte[] decodeFromGZIP(byte[] arr) throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(arr);
GZIPInputStream gzip = new GZIPInputStream(bais);
return gzip.readAllBytes();
}
public static byte[] encodeToGZIP(byte[] arr) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baos);
gzip.write(arr);
gzip.finish();
return baos.toByteArray();
}
public static String randomString(int count) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < count; i++) {
str.append(" ").append(UUID.randomUUID().toString());
}
return str.toString();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.