Java'da Base64 olarak kodlama


317

Java Base64 kodlama bazı verileri kodlamak gerekiyor. Bunu nasıl yaparım? Base64 kodlayıcı sağlayan sınıfın adı nedir?


sun.misc.BASE64EncoderDersi başarılı olmadan kullanmaya çalıştım . Java 7 kodu aşağıdaki satırı var:

wr.write(new sun.misc.BASE64Encoder().encode(buf));

Eclipse kullanıyorum. Eclipse bu satırı bir hata olarak işaretler. Gerekli kütüphaneleri içe aktardım:

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

Fakat yine de, her ikisi de hata olarak gösterilir. Burada benzer bir yazı buldum .

Apache Commons'ı aşağıdakileri dahil ederek önerilen çözüm olarak kullandım:

import org.apache.commons.*;

ve http://commons.apache.org/codec/ adresinden indirilen JAR dosyalarını içe aktarma

Ama sorun hala var. Tutulma daha önce bahsedilen hataları gösteriyor. Ne yapmalıyım?


7
Tavsiyem: hata mesajını okuyun ve ne dediğini anlamaya çalışın.
JB Nizet

27
Altında ders kullanmanız gerekmiyorsun.**
onon15 15

16
Bunlar herkese açık API'nın bir parçası değildir; bunlar önceden haber verilmeksizin değiştirilebilir, çıkarılabilir veya her neyse. Bazıları deneysel olabilir veya sadece üretim sınıfı olmayabilir. oracle.com/technetwork/java/faq-sun-packages-142232.html
onon15

5
Veya Java 6 ve sonraki sürümlerde standart olarak bulunan JAXB DatatypeConverter'ı kullanın .
Ian Roberts

9
java.util.Base64 Java 8'de kullanılabilir
earcam

Yanıtlar:


621

Sınıfınızın içe aktarılmasını değiştirmeniz gerekiyor:

import org.apache.commons.codec.binary.Base64;

Ve sonra sınıfınızı Base64 sınıfını kullanacak şekilde değiştirin.

İşte bazı örnek kod:

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));

O zaman neden sun. * Paketlerini kullanmamanız gerektiğini okuyun .


Güncelleme (2016-12-16)

Artık java.util.Base64Java 8 ile kullanabilirsiniz . İlk olarak, normal şekilde yaptığınız gibi içe aktarın:

import java.util.Base64;

Ardından Base64 statik yöntemlerini aşağıdaki gibi kullanın:

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));

Dizeyi doğrudan kodlamak ve sonucu kodlanmış dize olarak almak istiyorsanız, bunu kullanabilirsiniz:

String encodeBytes = Base64.getEncoder().encodeToString((userName + ":" + password).getBytes());

Daha fazla bilgi için Base64 için Java belgelerine bakın .


Bunun çalışması için herhangi bir harici paket indirmem gerekiyor mu? Evet ise, hangisi?
iptal edildi

2
Hayır bir şey indirmek gerekmez afaik
pratnala

16
org.apache.commons.codec.binary.Base64 varsayılan bir kütüphane gibi görünmüyor. Sanırım bunun için apache ortaklarını eklemelisin. Sağ?
Robert Reiz

@Frank Bir kerede bayt kod çözme OutOfMemory hata yükseltin.Herhangi bir fikir tampon içinde işlemek
xyz

225

Java 8'in eğlenceye katılmak için asla geç olmayan sınıfını kullanın: java.util.Base64

new String(Base64.getEncoder().encode(bytes));

11
Önemsiz bir yorum olmasına rağmen, Java'nın eski sürümleriyle uyumlu olmadığınızı (en azından bu noktada) muhtemelen çok daha yaygın olduğunu unutmayın.
dcoder

Ayrıca Java 8'in sınıfının mümkün olduğunu seçerdim. Şu anda bahar projemizden apache commons kütüphanesini kaldırmak için bir sınıf üzerinde çalışıyorum. Çoğu şey Bahar kütüphaneleri veya jdk yöntemiyle kolayca değiştirilebilir.
Adrian Cosma

68

Java 8'de şu şekilde yapılabilir: Base64.getEncoder (). EncodeToString (string.getBytes (StandardCharsets.UTF_8))

İşte kısa, bağımsız bir tam örnek:

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);
    }
}

Çıktı:

old crow medicine show => b2xkIGNyb3cgbWVkaWNpbmUgc2hvdw==

3
Java standart kitaplığında neden Charset sabitleri yok, neden ?!
Lukasz Wiktor

4
Güzel soru Lukasz! Aslında var. Unuttum! java.nio.charset.StandardCharsets. Cevabımı düzenleyeceğim. Bkz. Stackoverflow.com/questions/1684040/…
Kirby

67

Base64 kodlamasını kullanarak da dönüştürebilirsiniz. Bunu yapmak için javax.xml.bind.DatatypeConverter#printBase64Binaryyöntemi kullanabilirsiniz .

Örneğin:

byte[] salt = new byte[] { 50, 111, 8, 53, 86, 35, -19, -47 };
System.out.println(DatatypeConverter.printBase64Binary(salt));

4
Bu çalışırken, belgeler özellikle şunları belirtir: DatatypeConverterInterface yalnızca JAXB sağlayıcısının kullanımı içindir.
gebirgsbärbel

11
@Gebirgsbaerbel yanlış olduğunu düşünüyorum, printX () ve parseX () yöntemi herhangi biri tarafından kullanılabilir, JAXB için olan tek şey setDatatypeConverter()yöntemdir (sonra JAXB sağlayıcıları için çağrılmalıdır).
PhoneixS

9
Sonunda Java 8'den Base64 sınıfı olacak gitmek için bir yol. Ancak bu arada Java 7'yi hedeflemeniz gerekiyorsa, harici kütüphanelere bağlı olmadığı için bu çözüm güzeldir.
dana

4
Bu, Java 9 altında çalışmaz. Daha da kötüsü, Java 7 için javax.xml.bind. * Kullanılarak derlenen kod Java 9 altında Çalışma Zamanı'nda başarısız olur.
Stephen M -on strike-

21

Google Guava , Base64 verilerini kodlamak ve kodunu çözmek için başka bir seçenektir:

POM yapılandırması:

<dependency>
   <artifactId>guava</artifactId>
   <groupId>com.google.guava</groupId>
   <type>jar</type>
   <version>14.0.1</version>
</dependency>

Basit kod:

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

10

Eclipse, genel API'nin parçası olmayan bir JDK satıcısına özgü dahili sınıfları kullanmaya çalıştığınız için size bir hata / uyarı verir. Jakarta Commons, elbette farklı bir pakette bulunan base64 kodeklerinin kendi uygulamasını sağlar. Bu ithalatları silin ve Eclipse'in sizin için uygun Commons sınıflarını içe aktarmasına izin verin.


Cakarta projesi artık . Karışık ve eşleştirilmiştir (ve adı Java EE için yeniden kullanılmıştır ). Cevabınızı güncelleyip bazı referanslar verebilir misiniz? Örneğin, şimdi olduğu sınıf Base64içindeorg.apache.commons.codec.binary ? Şimdi bu bağlam için Apache Commons mı?
Peter Mortensen

9

Bunu dönüştürmek için, Java'da açık kaynaklı Base64 kodlayıcı / kod çözücü olan Base64Coder'den alacağınız bir kodlayıcı ve kod çözücüye ihtiyacınız var . Bu ihtiyacınız olacak Base64Coder.java dosyasıdır .

Şimdi gereksiniminize göre bu sınıfa erişmek için aşağıdaki sınıfa ihtiyacınız olacak:

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'de bitmap'inizi bir sunucuya veya web hizmetine Yükleme için Base64'e dönüştürebilirsiniz.

Bitmap bmImage = //Data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmImage.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] imageData = baos.toByteArray();
String encodedImage = Base64.encodeArray(imageData);

Bu “encodedImage” resminizin metin temsilidir. Bunu yükleme amacıyla veya aşağıdaki gibi bir HTML sayfasına doğrudan aktarmak için kullanabilirsiniz ( referans ):

<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" />

Belgeler: http://dwij.co.in/java-base64-image-encoder


Son bağlantı (dwij.co.in) bozuk (404).
Peter Mortensen


9

İşte iki sentim ... Java 8 kendi Base64 uygulamasını içeriyor . Ancak, biraz rahatsız edici bir fark buldum. Göstermek için bir kod örneği vereceğim:

Codec sarma makinem:

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);
  }
}

Test Sınıfı:

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));
  }
}

ÇIKTI:

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 kodlu metnin sonunda ek satır sonları (beyaz boşluklar) içerdiğine dikkat edin. Bu nedenle, kod64'ümün Base64 uygulamasından bağımsız olarak aynı sonucu vermesi trim()için Apache kodlu metni çağırmak zorunda kaldım . Benim durumumda, yukarıda belirtilen yöntem çağrısını codec bileşenime apacheDecode()şöyle ekledim :

return Base64.encodeBase64String(decodedByteArr).trim();

Bu değişiklik yapıldıktan sonra, sonuçlarla başlamam bekleniyor:

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!

SONUÇ : Apache Base64'ten Java'ya geçmek istiyorsanız:

  1. Kodlanmış metni Apache kod çözücünüzle çözün.
  2. Elde edilen (düz) metni Java ile kodlayın.

Bu adımları izlemeden geçiş yaparsanız büyük olasılıkla sorunla karşılaşırsınız. Bu keşfi böyle yaptım.


8

Android'de android.util.Base64 yardımcı programı sınıfının statik yöntemlerini kullanın . Başvurulan belgeler Base64 sınıfının API seviye 8'e ( Android 2.2 (Froyo)) eklendiğini söylüyor .

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));

Android için geliştiriyorsanız ve Java 8'i kullanamıyorsanız en iyi cevap budur.
Craig Brown

6

Apache Commons güzel bir Base64 uygulaması var. Bunu şu şekilde yapabilirsiniz:

// 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 kodlaması hakkında daha fazla bilgiyi Java ve JavaScript kullanarak Base64 kodlamasında bulabilirsiniz .


Bunun, dizenin varsayılan karakter kümesinde kodlanmış olduğunu varsaydığını unutmayın
Kirby

6

Eğer kullanıyorsanız Bahar Çerçeve en azından sürüm 4.1, kullanabileceğiniz org.springframework.util.Base64Utils sınıfı:

byte[] raw = { 1, 2, 3 };
String encoded = Base64Utils.encodeToString(raw);
byte[] decoded = Base64Utils.decodeFromString(encoded);

Neyin mevcut olduğuna bağlı olarak Java 8'in Base64, Apache Commons Codec veya JAXB DatatypeConverter'e delege edecektir.


4

Java 8 ile basit örnek:

import java.util.Base64;

String str = "your string";
String encodedStr = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));

3

Java 7'de bu yöntemi kodladım

import javax.xml.bind.DatatypeConverter;

public static String toBase64(String data) {
    return DatatypeConverter.printBase64Binary(data.getBytes());
}

Java 7 ve 8 altında çalışır, ancak Java 9'da çalışmaz. Daha da kötüsü, bunu Java 7 veya 8 altında oluşturursanız, derlenir ve daha sonra Java 9 altında Runtime'da bir ClassDefNotFoundException elde edersiniz.
Stephen M -on strike-


1

Aşağıdaki kod snippet'i ile denedim. İyi çalıştı. :-)

com.sun.org.apache.xml.internal.security.utils.Base64.encode("The string to encode goes here");

0
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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.