Кодирование как Base64 в Java
Мне нужно закодировать некоторые данные в кодировке Base64 в Java. Как мне это сделать? Как называется класс, предоставляющий кодировщик Base64?
Я пытался использовать класс sun.misc.BASE64Encoder
, но безуспешно. У меня есть следующая строка кода 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/
Но проблема все еще существует. Затмение все еще показывает ошибки, упомянутые ранее; пожалуйста, порекомендуйте.
Ответы
Ответ 1
Вам нужно изменить импорт вашего класса:
import org.apache.commons.codec.binary.Base64;
А затем измените свой класс на использование класса Base64.
Вот пример кода:
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. *.
Обновление (16.12.2016)
Теперь вы можете java.util.Base64
с Java8. Во-первых, импортируйте его как обычно:
import java.util.Base64;
Затем используйте статические методы Base64 следующим образом:
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());
См. Javadocs для Base64: https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html
Ответ 2
Используйте класс Java 8, который никогда не был слишком поздним, чтобы присоединиться к классу: java.util.Base64
Ответ 3
Вы также можете конвертировать с использованием кодировки base64. Для этого вы можете использовать javax.xml.bind.DatatypeConverter#printBase64Binary
метод
Например:
byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));
Ответ 4
В 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);
}
}
выводит вывод
old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==
Ответ 5
Google Guava - это еще один вариант кодирования и декодирования данных base64:
Конфигурация POM:
<dependency>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
<type>jar</type>
<version>14.0.1</version>
</dependency>
Пример кода:
String inputContent = "Hello Việt Nam";
String base64String = BaseEncoding.base64().encode(inputContent.getBytes("UTF-8"));
//decode
System.out.println("Base64:" + base64String);//SGVsbG8gVmnhu4d0IE5hbQ==
byte[] contentInBytes = BaseEncoding.base64().decode(base64String);
System.out.println("Source content: " + new String(contentInBytes, "UTF-8"));//Hello Việt Nam
Ответ 6
Eclipse дает вам сообщение об ошибке/предупреждении, поскольку вы пытаетесь использовать внутренние классы, специфичные для поставщика JDK, а не часть публичного API. Jakarta Commons обеспечивает собственную реализацию кодеков base64, которые, конечно, находятся в другом пакете. Удалите этот импорт и пусть Eclipse импортирует соответствующие классы Commons для вас.
Ответ 7
Для java 6-7 лучшим вариантом является заимствование кода из репозитория Android. Он не имеет зависимостей.
https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Base64.java
Ответ 8
Вот мои два цента... 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);
}
}
Тестовый класс:
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));
}
}
ВЫХОД:
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, мне пришлось вызывать trim()
для текста, закодированного в Apache. В моем случае я просто добавил вышеупомянутый вызов метода в мой кодек 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!
Возможно, кто-то мог бы прокомментировать, почему это так, но я нашел мой обходной путь приемлемым компромиссом.
Ответ 9
Для этого вам потребуется Encoder и Decoder, который вы получите от http://www.source-code.biz/base64coder/java/. Это файл Base64Coder.java, который вам понадобится.
Теперь для доступа к этому классу согласно вашему требованию вам понадобится класс ниже:
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 для загрузки на сервер/веб-службу.
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" />
Документация: http://dwij.co.in/java-base64-image-encoder
Ответ 10
В Android используйте статические методы служебного класса android.util.Base64. В указанной документации говорится, что класс Base64 был добавлен на уровне API 8 (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));
Ответ 11
Apache имеет хорошую реализацию 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));
вы можете найти более подробную информацию о кодировке base64 в http://faisalbhagat.blogspot.com/2014/06/base64-encoding-using-java-and.html
Ответ 12
Если вы используете фреймворк Spring, по крайней мере, версию 4.1, вы можете использовать класс org.springframework.util.Base64Utils:
byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);
Он будет делегировать Java 8 Base64, Apache Commons Codec или JAXB DatatypeConverter, в зависимости от того, что доступно.
Ответ 13
Простой пример с Java 8:
import java.util.Base64;
String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
Ответ 14
В Java 7 я закодировал этот метод
import javax.xml.bind.DatatypeConverter;
public static String toBase64(String data) {
return DatatypeConverter.printBase64Binary(data.getBytes());
}
Ответ 15
Если вы придерживаетесь более ранней версии Java, чем 8, но уже используете AWS SDK для Java, вы можете использовать com.amazonaws.util.Base64.
Ответ 16
Я попробовал следующий фрагмент кода. Он работал хорошо.: -)
com.sun.org.apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");
Ответ 17
public class EncryptionDecrption {
private static final String ALGO = "AES";
private static final byte[] keyValue = new byte[]{'T', 'h', 'e', 'R', 'o', 'o', 'K', 'n', 'a', 't','E','n', 'i', 'r','i','n'};
public EncryptionDecrption(){
}
public static String setEncryptedString(String data) throws Exception {
Key key = getKey();
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedValue = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.encodeToString(encryptedValue, Base64.DEFAULT);
}
public static String getDecryptedValue(String data) throws Exception {
if(data != null) {
Key key = getKey();
Cipher cipher = Cipher.getInstance(ALGO);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decodebyte = Base64.decode(data.getBytes("UTF-8"), Base64.DEFAULT);
byte[] decValue = cipher.doFinal(decodebyte);
return new String(decValue);
}
return null;
}
private static Key getKey() throws Exception {
return new SecretKeySpec(keyValue, ALGO);
}
}
он работает для меня в Android.