ถอดรหัสข้อมูล Base64 ใน Java


480

ฉันมีภาพที่เข้ารหัส Base64 วิธีที่ดีที่สุดในการถอดรหัสใน Java คืออะไร? หวังว่าจะใช้เฉพาะห้องสมุดที่มาพร้อมกับ Sun Java 6


1
ไม่ว่าคุณจะใช้แอปประเภทใด (ทดลองหรือไม่ก็ตาม) เพียงแค่สร้างไฟล์ Base64.java เดียวในแพ็คเกจ utils ของคุณโดยใช้รหัสที่นี่: migbase64.sourceforge.netดูแผนภูมิประสิทธิภาพและสังเกตเห็นความแตกต่าง: เร็ว 4-5 เท่า
javacoder

FYI: JEP 135เสนอให้แนะนำ API มาตรฐานที่สามารถค้นพบได้ในแพลตฟอร์ม Java
Jesse Glick

ความคืบหน้าเกิดขึ้น: mail.openjdk.java.net/pipermail/core-libs-dev/2012-October/...
JodaStephen

2
ที่นี่เลยคือการดำเนินการอื่นที่ฉันเพิ่งผ่านกัน: github.com/n1hility/playground/blob/master/src/main/java/org/...
เจสันกรีน

3
โปรดทราบว่าหากคุณกำลังพัฒนาแอพ Android Google ได้ทำสิ่งนี้แล้ว: developer.android.com/reference/android/util/Base64.html
Raphael Oliveira

คำตอบ:


419

ในฐานะของ v6, Java SE มาพร้อมกับ JAXB javax.xml.bind.DatatypeConverterมีวิธีคงที่ที่ทำให้ง่าย ดูและparseBase64Binary()printBase64Binary()


20
อย่างไรก็ตามดูเหมือนว่าprintBase64Binary(..)วิธีการดังกล่าวจะไม่ทำ Base MIME ของรุ่น MIME ( en.wikipedia.org/wiki/Base64#MIME ) ในขณะที่ Sun ส่วนตัวและการใช้งานคอมมอนส์ใช้สิ่งนี้ โดยเฉพาะสำหรับ String ที่มีขนาดใหญ่กว่า 76 ตัวอักษรจะมีการเพิ่มบรรทัดใหม่ ฉันไม่พบวิธีกำหนดค่าการใช้งาน JAXB สำหรับพฤติกรรมนี้ ... :-(
KLE

7
อย่างไรก็ตามการดำเนินการของดวงอาทิตย์จะไม่สนใจบรรทัดใหม่ ดังนั้นพวกเขาเข้ากันได้
Esben Skov Pedersen

9
คำเตือน! parseBase64Binary จะข้ามอักขระที่ไม่ถูกต้องไปอย่างเงียบ ๆ และจะไม่ตรวจสอบความถูกต้องของ base64 เป็นการดีกว่าที่จะใช้ Commons Codec หรือ Guava Base64 โปรดทราบว่า Guava ปฏิเสธบรรทัดใหม่และอักขระช่องว่างดังนั้นคุณต้องแยกสตริงด้วย whitespaces ที่ละเว้น: BaseEncoding.base64 (). ถอดรหัส (s.replaceAll ("\\ s", ""))
Martin Vysny

9
ระวัง. ฟังก์ชั่นนี้ใช้ไม่ได้กับข้อมูลที่ยาวกว่า 65000 (เวอร์ชั่น java 1.6)
HüseyinYağlı

5
อย่าใช้เพราะคุณจะได้รับปัญหาใน jdk 9: java.lang.NoClassDefFoundError (javax / xml / bind /
DatatypeConverter

381

ในฐานะของJava 8มี API ที่สนับสนุนอย่างเป็นทางการสำหรับการเข้ารหัสและถอดรหัส Base64 ในเวลานี้อาจเป็นตัวเลือกเริ่มต้น

API มีคลาสjava.util.Base64และคลาสที่ซ้อนอยู่ สนับสนุนสามรสชาติที่แตกต่าง: พื้นฐานปลอดภัย URL และ MIME

โค้ดตัวอย่างที่ใช้การเข้ารหัส "พื้นฐาน":

import java.util.Base64;

byte[] bytes = "Hello, World!".getBytes("UTF-8");
String encoded = Base64.getEncoder().encodeToString(bytes);
byte[] decoded = Base64.getDecoder().decode(encoded);

เอกสารjava.util.Base64รวมถึงวิธีการอีกหลายสำหรับการกำหนดค่าเข้ารหัสและถอดรหัสและการใช้เรียนแตกต่างกันเป็นปัจจัยการผลิตและผล (อาร์เรย์ไบต์สตริง ByteBuffers ลำธาร java.io)


1
ฉันใช้ Java 8 นี่เป็นวิธีที่แนะนำหรือไม่หากใช้ Java 8
JohnMerlino

4
@JohnMerlino หากไม่รองรับความเข้ากันได้กับรุ่น Java รุ่นเก่าฉันขอแนะนำให้ใช้ API นี้เนื่องจาก JRE มีนโยบายความเข้ากันได้ดีกว่าไลบรารีส่วนใหญ่ นอกจากนี้เมื่อรวมอยู่ใน JRE แล้วก็ไม่ได้ จำกัด การพึ่งพาของคุณในทางที่เป็นไปได้
Andrea

4
Java 7 is EOLed, Java 9 มาแล้วนี่เป็นคำตอบที่ถูกต้องสำหรับฉัน!
eskatos

1
เกือบจะดี: สิ่งนี้ยอมรับเฉพาะสตรีมเบสเบส 64 ดิบเท่านั้นไม่ใช่ไฟล์เบส 64 ฉันต้องใช้final byte[] decoded = Base64.getMimeDecoder().decode(encoded);แทน แต่ขอบคุณล่ะ! (ดีกับคอมมอนส์ - io FileUtils.readFileToByteArrayและFileUtils.writeByteArrayToFile- โดยเฉพาะอย่างยิ่งเมื่อคุณรู้ว่าencodedสามารถเป็นได้byte[]เช่นกัน)
mirabilos

101

ไม่จำเป็นต้องใช้คอมมอนส์ - Sun ส่งตัวเข้ารหัส base64 พร้อม Java คุณสามารถนำเข้าได้เช่น:

import sun.misc.BASE64Decoder;

แล้วใช้มันเช่นนี้

BASE64Decoder decoder = new BASE64Decoder();
byte[] decodedBytes = decoder.decodeBuffer(encodedBytes);

ในกรณีที่encodedBytesเป็นทั้งหรือjava.lang.String java.io.InputStreamเพียงแค่ระวังว่าsun.*ชั้นเรียนไม่ได้ "สนับสนุนอย่างเป็นทางการ" โดยซัน

แก้ไข:ใครจะรู้ว่านี่จะเป็นคำตอบที่ถกเถียงกันมากที่สุดที่ฉันเคยโพสต์? ฉันรู้ว่าดวงอาทิตย์ * แพ็คเกจไม่ได้รับการสนับสนุนหรือรับประกันว่าจะยังคงอยู่ต่อไปและฉันรู้เกี่ยวกับคอมมอนส์และใช้งานได้ตลอดเวลา อย่างไรก็ตามโปสเตอร์ขอให้ชั้นเรียนที่ "รวมอยู่กับ Sun Java 6" และนั่นคือสิ่งที่ฉันพยายามที่จะตอบ ฉันยอมรับว่าคอมมอนส์เป็นวิธีที่ดีที่สุดในการเข้าชมโดยทั่วไป

แก้ไข 2:ตามคะแนน amir75 ด้านล่าง Java 6+ มาพร้อมกับ JAXB ซึ่งมีรหัสที่รองรับเพื่อเข้ารหัส / ถอดรหัส Base64 โปรดดูคำตอบของ Jeremy Rossด้านล่าง


195
-1 - นี่คือรหัส Sun ภายในไม่ใช่ส่วนหนึ่งของ J2SE (ไม่ใช่พกพา) และอาจหายไปเมื่อใดก็ได้ - Sun กล่าวอย่างชัดเจนว่าห้ามใช้ไลบรารีภายในในรหัสผู้ใช้
kdgregory

59
จริงดังนั้นข้อจำกัดความรับผิดชอบของฉันในตอนท้าย
MattK

20
นี่เป็นโครงการระยะสั้นและเป็นเพียงการทดลองและไม่ต้องการผ่านขั้นตอนการอนุมัติสำหรับห้องสมุดใหม่ นี่คือคำตอบที่ถูกต้องสำหรับคำถามนี้
Ryan P

44
Bzzt ในสภาพแวดล้อมแบบมืออาชีพการใช้คุณสมบัติที่ไม่ได้รับการสนับสนุนและไม่มีเอกสารนั้นไม่ใช่การตัดสินใจที่ถูกต้อง และในสภาพแวดล้อมขององค์กร "การทดลอง" กลายเป็น "รหัสการผลิต" โดยไม่มีโอกาสแก้ไขแฮ็ก
kdgregory

29
ในแผนกวิจัยที่มีการทำเครื่องหมายรหัสว่าเป็นการทดสอบและเมื่อมีการทำเครื่องหมายถูกทิ้งไว้เสมอจะเป็นการตัดสินใจที่ถูกต้อง
Ryan P

55

เฉพาะในCommons Codec : class Base64ถึงdecode(byte[] array)หรือencode(byte[] array)


7
คุณสามารถเชื่อมโยงข้อความ 'Commons Codec' ไปยังหน้าโครงการ วิธีการที่คำตอบนี้จะดีกว่าเควิน :)
mmutilva

1
ฉันรู้ว่านี่เป็นคำถามเก่า แต่ทำไมนี่ไม่ใช่คำตอบที่ยอมรับ ตัวแปลงสัญญาณคอมมอนส์ไม่รวมอยู่ในการติดตั้งจาวาส่วนใหญ่และมีรหัสน้อยกว่าการใช้งานมากกว่าการวางเวอร์ชั่นของคุณเองหรือ
Li Haoyi

2
@LiHaoyi คำถามที่ถามถึงห้องสมุดที่มาพร้อมกับ JDK ของ Sun ซึ่งไม่รวมอะไรจาก Commons
Ti Strga

1
แทร็กผิด ๆ วิธีการเหล่านี้ไม่มีอยู่จริง!
Nicolas Barbulesco

36

ปัจจุบัน Guava มีการถอดรหัส Base64 ในตัวแล้ว

ใช้BaseEncoding.base64 (). decode ()

สำหรับการจัดการกับช่องว่างที่เป็นไปได้ในการใช้งานอินพุต

BaseEncoding.base64().decode(CharMatcher.WHITESPACE.removeFrom(...));

ดูการสนทนานี้สำหรับข้อมูลเพิ่มเติม


1
Guava 14 ยังคงเป็นผู้สมัคร แต่ก็ยังได้รับ upvote ของฉัน - ตามเวลาที่มันถึงตำแหน่งที่เหมาะสมใด ๆ มันควรจะเป็นสีทอง :-)
Peter Becker

1
ตัวถอดรหัส base64 ของ Guava ปฏิเสธอักขระขึ้นบรรทัดใหม่และช่องว่างดังนั้นคุณต้องลบออกก่อน
Martin Vysny

34

โซลูชันของฉันเร็วและง่ายที่สุด

public class MyBase64 {

    private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();

    private static int[]  toInt   = new int[128];

    static {
        for(int i=0; i< ALPHABET.length; i++){
            toInt[ALPHABET[i]]= i;
        }
    }

    /**
     * Translates the specified byte array into Base64 string.
     *
     * @param buf the byte array (not null)
     * @return the translated Base64 string (not null)
     */
    public static String encode(byte[] buf){
        int size = buf.length;
        char[] ar = new char[((size + 2) / 3) * 4];
        int a = 0;
        int i=0;
        while(i < size){
            byte b0 = buf[i++];
            byte b1 = (i < size) ? buf[i++] : 0;
            byte b2 = (i < size) ? buf[i++] : 0;

            int mask = 0x3F;
            ar[a++] = ALPHABET[(b0 >> 2) & mask];
            ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
            ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
            ar[a++] = ALPHABET[b2 & mask];
        }
        switch(size % 3){
            case 1: ar[--a]  = '=';
            case 2: ar[--a]  = '=';
        }
        return new String(ar);
    }

    /**
     * Translates the specified Base64 string into a byte array.
     *
     * @param s the Base64 string (not null)
     * @return the byte array (not null)
     */
    public static byte[] decode(String s){
        int delta = s.endsWith( "==" ) ? 2 : s.endsWith( "=" ) ? 1 : 0;
        byte[] buffer = new byte[s.length()*3/4 - delta];
        int mask = 0xFF;
        int index = 0;
        for(int i=0; i< s.length(); i+=4){
            int c0 = toInt[s.charAt( i )];
            int c1 = toInt[s.charAt( i + 1)];
            buffer[index++]= (byte)(((c0 << 2) | (c1 >> 4)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c2 = toInt[s.charAt( i + 2)];
            buffer[index++]= (byte)(((c1 << 4) | (c2 >> 2)) & mask);
            if(index >= buffer.length){
                return buffer;
            }
            int c3 = toInt[s.charAt( i + 3 )];
            buffer[index++]= (byte)(((c2 << 6) | c3) & mask);
        }
        return buffer;
    } 

}

15
มันไม่ใช่รถ! - อ่านความคิดเห็น javadoc ... พารามิเตอร์ของการถอดรหัส (.. ) เป็นbase64 String ไม่ใช่แค่สตริงใด ๆ byte[] b1 = {1,2,3}; byte[] b2 = decode(encode(b1)); System.out.println(Arrays.equals( b1, b2 ));// => จริง
GeorgeK

9
เร็วที่สุดและง่ายที่สุด? บูรณาการล้อหรือไม่!
Nicolas Barbulesco

7
ฉันทดสอบการเปรียบเทียบคลาสนี้กับคอมมอนส์ - ตัวแปลงสัญญาณและดูเหมือนว่าจะใช้ได้ ฉันต้องการสิ่งที่ง่ายเช่นนี้เพราะฉันต้องการเพียงการเข้ารหัส base64 และไม่ต้องการสิ่งพิเศษทั้งหมดที่คอมมอนส์ - ตัวแปลงสัญญาณให้ขอบคุณ
Michael

2
เชื่อใจได้ไหม? ดูเหมือนจะง่ายที่สุดหากคุณไม่ต้องการนำเข้าไลบรารีภายนอก
เฟลิเป้

2
มันไม่ได้ทำงานร่วมกับไบต์ที่ได้รับจากอัลกอริทึม AES
shontauro

11

นี่คือการดำเนินการของฉันเองหากเป็นประโยชน์กับบางคน:

public class Base64Coder {

    // The line separator string of the operating system.
    private static final String systemLineSeparator = System.getProperty("line.separator");

    // Mapping table from 6-bit nibbles to Base64 characters.
    private static final char[] map1 = new char[64];
       static {
          int i=0;
          for (char c='A'; c<='Z'; c++) map1[i++] = c;
          for (char c='a'; c<='z'; c++) map1[i++] = c;
          for (char c='0'; c<='9'; c++) map1[i++] = c;
          map1[i++] = '+'; map1[i++] = '/'; }

    // Mapping table from Base64 characters to 6-bit nibbles.
    private static final byte[] map2 = new byte[128];
       static {
          for (int i=0; i<map2.length; i++) map2[i] = -1;
          for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }

    /**
    * Encodes a string into Base64 format.
    * No blanks or line breaks are inserted.
    * @param s  A String to be encoded.
    * @return   A String containing the Base64 encoded data.
    */
    public static String encodeString (String s) {
       return new String(encode(s.getBytes())); }

    /**
    * Encodes a byte array into Base 64 format and breaks the output into lines of 76 characters.
    * This method is compatible with <code>sun.misc.BASE64Encoder.encodeBuffer(byte[])</code>.
    * @param in  An array containing the data bytes to be encoded.
    * @return    A String containing the Base64 encoded data, broken into lines.
    */
    public static String encodeLines (byte[] in) {
       return encodeLines(in, 0, in.length, 76, systemLineSeparator); }

    /**
    * Encodes a byte array into Base 64 format and breaks the output into lines.
    * @param in            An array containing the data bytes to be encoded.
    * @param iOff          Offset of the first byte in <code>in</code> to be processed.
    * @param iLen          Number of bytes to be processed in <code>in</code>, starting at <code>iOff</code>.
    * @param lineLen       Line length for the output data. Should be a multiple of 4.
    * @param lineSeparator The line separator to be used to separate the output lines.
    * @return              A String containing the Base64 encoded data, broken into lines.
    */
    public static String encodeLines (byte[] in, int iOff, int iLen, int lineLen, String lineSeparator) {
       int blockLen = (lineLen*3) / 4;
       if (blockLen <= 0) throw new IllegalArgumentException();
       int lines = (iLen+blockLen-1) / blockLen;
       int bufLen = ((iLen+2)/3)*4 + lines*lineSeparator.length();
       StringBuilder buf = new StringBuilder(bufLen);
       int ip = 0;
       while (ip < iLen) {
          int l = Math.min(iLen-ip, blockLen);
          buf.append (encode(in, iOff+ip, l));
          buf.append (lineSeparator);
          ip += l; }
       return buf.toString(); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in  An array containing the data bytes to be encoded.
    * @return    A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in) {
       return encode(in, 0, in.length); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in    An array containing the data bytes to be encoded.
    * @param iLen  Number of bytes to process in <code>in</code>.
    * @return      A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in, int iLen) {
       return encode(in, 0, iLen); }

    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted in the output.
    * @param in    An array containing the data bytes to be encoded.
    * @param iOff  Offset of the first byte in <code>in</code> to be processed.
    * @param iLen  Number of bytes to process in <code>in</code>, starting at <code>iOff</code>.
    * @return      A character array containing the Base64 encoded data.
    */
    public static char[] encode (byte[] in, int iOff, int iLen) {
       int oDataLen = (iLen*4+2)/3;       // output length without padding
       int oLen = ((iLen+2)/3)*4;         // output length including padding
       char[] out = new char[oLen];
       int ip = iOff;
       int iEnd = iOff + iLen;
       int op = 0;
       while (ip < iEnd) {
          int i0 = in[ip++] & 0xff;
          int i1 = ip < iEnd ? in[ip++] & 0xff : 0;
          int i2 = ip < iEnd ? in[ip++] & 0xff : 0;
          int o0 = i0 >>> 2;
          int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
          int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
          int o3 = i2 & 0x3F;
          out[op++] = map1[o0];
          out[op++] = map1[o1];
          out[op] = op < oDataLen ? map1[o2] : '='; op++;
          out[op] = op < oDataLen ? map1[o3] : '='; op++; }
       return out; }

    /**
    * Decodes a string from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param s  A Base64 String to be decoded.
    * @return   A String containing the decoded data.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static String decodeString (String s) {
       return new String(decode(s)); }

    /**
    * Decodes a byte array from Base64 format and ignores line separators, tabs and blanks.
    * CR, LF, Tab and Space characters are ignored in the input data.
    * This method is compatible with <code>sun.misc.BASE64Decoder.decodeBuffer(String)</code>.
    * @param s  A Base64 String to be decoded.
    * @return   An array containing the decoded data bytes.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decodeLines (String s) {
       char[] buf = new char[s.length()];
       int p = 0;
       for (int ip = 0; ip < s.length(); ip++) {
          char c = s.charAt(ip);
          if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
             buf[p++] = c; }
       return decode(buf, 0, p); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param s  A Base64 String to be decoded.
    * @return   An array containing the decoded data bytes.
    * @throws   IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (String s) {
       return decode(s.toCharArray()); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param in  A character array containing the Base64 encoded data.
    * @return    An array containing the decoded data bytes.
    * @throws    IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (char[] in) {
       return decode(in, 0, in.length); }

    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded input data.
    * @param in    A character array containing the Base64 encoded data.
    * @param iOff  Offset of the first character in <code>in</code> to be processed.
    * @param iLen  Number of characters to process in <code>in</code>, starting at <code>iOff</code>.
    * @return      An array containing the decoded data bytes.
    * @throws      IllegalArgumentException If the input is not valid Base64 encoded data.
    */
    public static byte[] decode (char[] in, int iOff, int iLen) {
       if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
       while (iLen > 0 && in[iOff+iLen-1] == '=') iLen--;
       int oLen = (iLen*3) / 4;
       byte[] out = new byte[oLen];
       int ip = iOff;
       int iEnd = iOff + iLen;
       int op = 0;
       while (ip < iEnd) {
          int i0 = in[ip++];
          int i1 = in[ip++];
          int i2 = ip < iEnd ? in[ip++] : 'A';
          int i3 = ip < iEnd ? in[ip++] : 'A';
          if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int b0 = map2[i0];
          int b1 = map2[i1];
          int b2 = map2[i2];
          int b3 = map2[i3];
          if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int o0 = ( b0       <<2) | (b1>>>4);
          int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
          int o2 = ((b2 &   3)<<6) |  b3;
          out[op++] = (byte)o0;
          if (op<oLen) out[op++] = (byte)o1;
          if (op<oLen) out[op++] = (byte)o2; }
       return out; }

    // Dummy constructor.
    private Base64Coder() {}
}

11

เป็นทางเลือกให้หรือห้องสมุดที่ไม่ใช่ธุรกิจหลักดูที่sun.misc.BASE64Decoderjavax.mail.internet.MimeUtility.decode()

public static byte[] encode(byte[] b) throws Exception {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    OutputStream b64os = MimeUtility.encode(baos, "base64");
    b64os.write(b);
    b64os.close();
    return baos.toByteArray();
}
public static byte[] decode(byte[] b) throws Exception {
    ByteArrayInputStream bais = new ByteArrayInputStream(b);
    InputStream b64is = MimeUtility.decode(bais, "base64");
    byte[] tmp = new byte[b.length];
    int n = b64is.read(tmp);
    byte[] res = new byte[n];
    System.arraycopy(tmp, 0, res, 0, n);
    return res;
}

เชื่อมโยงกับรหัสเต็ม: เข้ารหัส / ถอดรหัสไปยัง / จาก Base64


3
javax.mail ไม่ได้เป็นส่วนหนึ่งของหลัก
Adam Goode

javax.mail.internet.MimeUtility รวมอยู่ใน appengine-api.jar
diyism

9

อีกหนึ่งคำตอบที่ล่าช้า แต่การเปรียบเทียบของฉันแสดงให้เห็นว่าการติดตั้งใช้งานตัวเข้ารหัสBase64 ของ Jettyนั้นค่อนข้างเร็ว ไม่เป็นอย่างที่MiGBase64แต่เร็วกว่าiHarder Base64

import org.eclipse.jetty.util.B64Code;

final String decoded = B64Code.decode(encoded, "UTF-8");

ฉันยังทำเกณฑ์มาตรฐานด้วย:

      library     |    encode    |    decode   
------------------+--------------+-------------
 'MiGBase64'      |  10146001.00 |  6426446.00
 'Jetty B64Code'  |   8846191.00 |  3101361.75
 'iHarder Base64' |   3259590.50 |  2505280.00
 'Commons-Codec'  |    241318.04 |   255179.96

สิ่งเหล่านี้ทำงาน / วินาทีสูงกว่าดีกว่า


8

รับตัวอย่างการเข้ารหัส / ถอดรหัสการทดสอบของjavax.xml.bind.DatatypeConverterโดยใช้วิธีการparseBase64Binary ()และprintBase64Binary ()อ้างถึงคำตอบ @ jeremy-ross และ @nightfirecat

@Test
public void EncodeDecode() {
    //ENCODE
    String hello = "Hello World";
    byte[] helloBytes = hello.getBytes(StandardCharsets.UTF_8);
    String encodedHello = DatatypeConverter.printBase64Binary(helloBytes);
    LOGGER.info(hello + " encoded=> " + encodedHello);

    //DECODE
    byte[] encodedHelloBytes = DatatypeConverter.parseBase64Binary(encodedHello);
    String helloAgain = new String(encodedHelloBytes, StandardCharsets.UTF_8) ;
    LOGGER.info(encodedHello + " decoded=> " + helloAgain);

    Assert.assertEquals(hello, helloAgain);
}

ผลลัพธ์:

INFO - Hello World encoded=> SGVsbG8gV29ybGQ=
INFO - SGVsbG8gV29ybGQ= decoded=> Hello World

6

หากคุณต้องการโซลูชันที่อิงตามประสิทธิภาพคุณสามารถใช้ "MiGBase64"

http://migbase64.sourceforge.net/

public class Base64Test {
    public static void main(String[] args) {
    String encodeToString = Base64.encodeToString("JavaTips.net".getBytes(), true);
    System.out.println("encodeToString " + encodeToString);
    byte[] decodedBytes = Base64.decode(encodeToString.getBytes());
    System.out.println("decodedBytes " + new String(decodedBytes));
    }
}

MiGBase64 นั้นใช้งานง่ายเข้ารหัสได้ดีและรวดเร็ว ยินดีที่ได้รู้จัก Imby
mukama

อ้างอิงจากมาตรฐาน MiGBase64 ไม่ใช่การใช้งานที่เร็วที่สุดอีกต่อไปและตอนนี้มันล้าหลังทั้ง Apache Commons และ sun.misc.BASE64Decoder อย่างมีนัยสำคัญ
Andrea

3

นี่เป็นคำตอบที่ช้าแต่ Joshua Bloch ได้มอบหมายBase64ชั้นเรียนของเขา(เมื่อเขาทำงานให้กับ Sun, ahem, Oracle) ภายใต้java.util.prefsแพ็คเกจ คลาสนี้มีอยู่ตั้งแต่ JDK 1.4

เช่น

String currentString = "Hello World";
String base64String = java.util.prefs.Base64.byteArrayToBase64(currentString.getBytes("UTF-8"));

11
น่าเสียดายที่คลาส Base64 มีการเปิดเผยค่าเริ่มต้นดังนั้นจึงเป็น API สาธารณะแทบจะไม่
Glyn Normington

2
ทำไมไม่เพียงแค่อ้างถึงjava.util.Base64
Lukas Eder

@ LukasEder นั่นเป็นเพราะjava.util.Base64มีการเปิดตัวใน JDK 8 (และสูงกว่า) ไม่มีอยู่ในรีลีสก่อนหน้านี้
Buhake Sindi

3

หวังว่าจะช่วยให้คุณ:

import com.sun.org.apache.xml.internal.security.utils.Base64;
String str="Hello World";
String base64_str=Base64.encode(str.getBytes("UTF-8"));

หรือ:

String str="Hello World";
String base64_str="";
try
   {base64_str=(String)Class.forName("java.util.prefs.Base64").getDeclaredMethod("byteArrayToBase64", new Class[]{byte[].class}).invoke(null, new Object[]{str.getBytes("UTF-8")});
   }
catch (Exception ee) {}

java.util.prefs.Base64ทำงานในท้องถิ่นrt.jar,

แต่มันไม่ได้อยู่ในรายการ JRE Class White

และไม่อยู่ในคลาสที่พร้อมใช้งานซึ่งไม่ได้อยู่ในรายชื่อสีขาวของ GAE / J

น่าเสียดายมาก!

PS ใน android นั้นเป็นเรื่องง่ายเพราะมันandroid.util.Base64รวมอยู่ใน Android API ระดับ 8 แล้ว


2

คุณสามารถเขียนหรือดาวน์โหลดไฟล์จากสตริง Base64 ที่เข้ารหัส:

Base64 base64 = new Base64(); 
String encodedFile="JVBERi0xLjUKJeLjz9MKMSAwIG9iago8PCAKICAgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDIgMCBSCiAgIC9QYWdlTGF5b3V0IC9TaW5"; 
              byte[] dd=encodedFile.getBytes();
            byte[] bytes = Base64.decodeBase64(dd);

 response.setHeader("Content-disposition", "attachment; filename=\""+filename+"\"");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Expires", "-1");

            // actually send result bytes
            response.getOutputStream().write(bytes);

ทำงานให้ฉันและหวังว่าจะให้คุณ ...


2

การนำ Java 8 ไปใช้java.util.Base64ไม่มีการขึ้นต่อกันในคลาสที่เจาะจง Java 8 อื่น ๆ

ผมไม่แน่ใจว่านี้จะทำงานสำหรับ Java 6 โครงการ แต่ก็เป็นไปได้ที่จะคัดลอกและวางBase64.javaไฟล์ลงในโครงการ Java 7 และเรียบเรียงด้วยการปรับเปลี่ยนอื่น ๆ นอกเหนือจากการนำเข้า java.util.Arrays java.util.Objectsและไม่มีการ

หมายเหตุไฟล์ Base64.java นั้นอยู่ใน GNU GPL2


2

ฉันใช้android.util.base64มันใช้งานได้ดีโดยไม่ต้องพึ่งพาใด ๆ

การใช้งาน:

byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT);

แพ็คเกจ com.test;

import java.io.UnsupportedEncodingException;

/**
 * Utilities for encoding and decoding the Base64 representation of
 * binary data.  See RFCs <a
 * href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
 * href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
 */
public class Base64 {

    public static final int DEFAULT = 0;


    public static final int NO_PADDING = 1;


    public static final int NO_WRAP = 2;


    public static final int CRLF = 4;


    public static final int URL_SAFE = 8;


    public static final int NO_CLOSE = 16;

    //  --------------------------------------------------------
    //  shared code
    //  --------------------------------------------------------

    /* package */ static abstract class Coder {
        public byte[] output;
        public int op;

        public abstract boolean process(byte[] input, int offset, int len, boolean finish);


        public abstract int maxOutputSize(int len);
    }

    //  --------------------------------------------------------
    //  decoding
    //  --------------------------------------------------------


    public static byte[] decode(String str, int flags) {
        return decode(str.getBytes(), flags);
    }

    public static byte[] decode(byte[] input, int flags) {
        return decode(input, 0, input.length, flags);
    }


    public static byte[] decode(byte[] input, int offset, int len, int flags) {
        // Allocate space for the most data the input could represent.
        // (It could contain less if it contains whitespace, etc.)
        Decoder decoder = new Decoder(flags, new byte[len*3/4]);

        if (!decoder.process(input, offset, len, true)) {
            throw new IllegalArgumentException("bad base-64");
        }

        // Maybe we got lucky and allocated exactly enough output space.
        if (decoder.op == decoder.output.length) {
            return decoder.output;
        }

        // Need to shorten the array, so allocate a new one of the
        // right size and copy.
        byte[] temp = new byte[decoder.op];
        System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
        return temp;
    }

   static class Decoder extends Coder {       
        private static final int DECODE[] = {
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        };

        /**
         * Decode lookup table for the "web safe" variant (RFC 3548
         * sec. 4) where - and _ replace + and /.
         */
        private static final int DECODE_WEBSAFE[] = {
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
        };

        /** Non-data values in the DECODE arrays. */
        private static final int SKIP = -1;
        private static final int EQUALS = -2;


        private int state;   // state number (0 to 6)
        private int value;

        final private int[] alphabet;

        public Decoder(int flags, byte[] output) {
            this.output = output;

            alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
            state = 0;
            value = 0;
        }


        public int maxOutputSize(int len) {
            return len * 3/4 + 10;
        }

        /**
         * Decode another block of input data.
         *
         * @return true if the state machine is still healthy.  false if
         *         bad base-64 data has been detected in the input stream.
         */
        public boolean process(byte[] input, int offset, int len, boolean finish) {
            if (this.state == 6) return false;

            int p = offset;
            len += offset;

            int state = this.state;
            int value = this.value;
            int op = 0;
            final byte[] output = this.output;
            final int[] alphabet = this.alphabet;

            while (p < len) {                
                if (state == 0) {
                    while (p+4 <= len &&
                           (value = ((alphabet[input[p] & 0xff] << 18) |
                                     (alphabet[input[p+1] & 0xff] << 12) |
                                     (alphabet[input[p+2] & 0xff] << 6) |
                                     (alphabet[input[p+3] & 0xff]))) >= 0) {
                        output[op+2] = (byte) value;
                        output[op+1] = (byte) (value >> 8);
                        output[op] = (byte) (value >> 16);
                        op += 3;
                        p += 4;
                    }
                    if (p >= len) break;
                }

                int d = alphabet[input[p++] & 0xff];

                switch (state) {
                case 0:
                    if (d >= 0) {
                        value = d;
                        ++state;
                    } else if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;

                case 1:
                    if (d >= 0) {
                        value = (value << 6) | d;
                        ++state;
                    } else if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;

                case 2:
                    if (d >= 0) {
                        value = (value << 6) | d;
                        ++state;
                    } else if (d == EQUALS) {
                        // Emit the last (partial) output tuple;
                        // expect exactly one more padding character.
                        output[op++] = (byte) (value >> 4);
                        state = 4;
                    } else if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;

                case 3:
                    if (d >= 0) {
                        // Emit the output triple and return to state 0.
                        value = (value << 6) | d;
                        output[op+2] = (byte) value;
                        output[op+1] = (byte) (value >> 8);
                        output[op] = (byte) (value >> 16);
                        op += 3;
                        state = 0;
                    } else if (d == EQUALS) {
                        // Emit the last (partial) output tuple;
                        // expect no further data or padding characters.
                        output[op+1] = (byte) (value >> 2);
                        output[op] = (byte) (value >> 10);
                        op += 2;
                        state = 5;
                    } else if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;

                case 4:
                    if (d == EQUALS) {
                        ++state;
                    } else if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;

                case 5:
                    if (d != SKIP) {
                        this.state = 6;
                        return false;
                    }
                    break;
                }
            }

            if (!finish) {
                // We're out of input, but a future call could provide
                // more.
                this.state = state;
                this.value = value;
                this.op = op;
                return true;
            }


            switch (state) {
            case 0:
                break;
            case 1:
                this.state = 6;
                return false;
            case 2:
                output[op++] = (byte) (value >> 4);
                break;
            case 3:
               output[op++] = (byte) (value >> 10);
                output[op++] = (byte) (value >> 2);
                break;
            case 4:
                this.state = 6;
                return false;
            case 5:
                break;
            }

            this.state = state;
            this.op = op;
            return true;
        }
    }

    //  --------------------------------------------------------
    //  encoding
    //  --------------------------------------------------------    
    public static String encodeToString(byte[] input, int flags) {
        try {
            return new String(encode(input, flags), "US-ASCII");
        } catch (UnsupportedEncodingException e) {
            // US-ASCII is guaranteed to be available.
            throw new AssertionError(e);
        }
    }


    public static String encodeToString(byte[] input, int offset, int len, int flags) {
        try {
            return new String(encode(input, offset, len, flags), "US-ASCII");
        } catch (UnsupportedEncodingException e) {
            // US-ASCII is guaranteed to be available.
            throw new AssertionError(e);
        }
    }


    public static byte[] encode(byte[] input, int flags) {
        return encode(input, 0, input.length, flags);
    }


    public static byte[] encode(byte[] input, int offset, int len, int flags) {
        Encoder encoder = new Encoder(flags, null);

        // Compute the exact length of the array we will produce.
        int output_len = len / 3 * 4;

        // Account for the tail of the data and the padding bytes, if any.
        if (encoder.do_padding) {
            if (len % 3 > 0) {
                output_len += 4;
            }
        } else {
            switch (len % 3) {
                case 0: break;
                case 1: output_len += 2; break;
                case 2: output_len += 3; break;
            }
        }

        // Account for the newlines, if any.
        if (encoder.do_newline && len > 0) {
            output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
                (encoder.do_cr ? 2 : 1);
        }

        encoder.output = new byte[output_len];
        encoder.process(input, offset, len, true);

        assert encoder.op == output_len;

        return encoder.output;
    }

    /* package */ static class Encoder extends Coder {
        /**
         * Emit a new line every this many output tuples.  Corresponds to
         * a 76-character line length (the maximum allowable according to
         * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
         */
        public static final int LINE_GROUPS = 19;

        /**
         * Lookup table for turning Base64 alphabet positions (6 bits)
         * into output bytes.
         */
        private static final byte ENCODE[] = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
        };

        /**
         * Lookup table for turning Base64 alphabet positions (6 bits)
         * into output bytes.
         */
        private static final byte ENCODE_WEBSAFE[] = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
        };

        final private byte[] tail;
        /* package */ int tailLen;
        private int count;

        final public boolean do_padding;
        final public boolean do_newline;
        final public boolean do_cr;
        final private byte[] alphabet;

        public Encoder(int flags, byte[] output) {
            this.output = output;

            do_padding = (flags & NO_PADDING) == 0;
            do_newline = (flags & NO_WRAP) == 0;
            do_cr = (flags & CRLF) != 0;
            alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;

            tail = new byte[2];
            tailLen = 0;

            count = do_newline ? LINE_GROUPS : -1;
        }

        /**
         * @return an overestimate for the number of bytes {@code
         * len} bytes could encode to.
         */
        public int maxOutputSize(int len) {
            return len * 8/5 + 10;
        }

        public boolean process(byte[] input, int offset, int len, boolean finish) {
            // Using local variables makes the encoder about 9% faster.
            final byte[] alphabet = this.alphabet;
            final byte[] output = this.output;
            int op = 0;
            int count = this.count;

            int p = offset;
            len += offset;
            int v = -1;

            // First we need to concatenate the tail of the previous call
            // with any input bytes available now and see if we can empty
            // the tail.

            switch (tailLen) {
                case 0:
                    // There was no tail.
                    break;

                case 1:
                    if (p+2 <= len) {
                        // A 1-byte tail with at least 2 bytes of
                        // input available now.
                        v = ((tail[0] & 0xff) << 16) |
                            ((input[p++] & 0xff) << 8) |
                            (input[p++] & 0xff);
                        tailLen = 0;
                    };
                    break;

                case 2:
                    if (p+1 <= len) {
                        // A 2-byte tail with at least 1 byte of input.
                        v = ((tail[0] & 0xff) << 16) |
                            ((tail[1] & 0xff) << 8) |
                            (input[p++] & 0xff);
                        tailLen = 0;
                    }
                    break;
            }

            if (v != -1) {
                output[op++] = alphabet[(v >> 18) & 0x3f];
                output[op++] = alphabet[(v >> 12) & 0x3f];
                output[op++] = alphabet[(v >> 6) & 0x3f];
                output[op++] = alphabet[v & 0x3f];
                if (--count == 0) {
                    if (do_cr) output[op++] = '\r';
                    output[op++] = '\n';
                    count = LINE_GROUPS;
                }
            }

            // At this point either there is no tail, or there are fewer
            // than 3 bytes of input available.

            // The main loop, turning 3 input bytes into 4 output bytes on
            // each iteration.
            while (p+3 <= len) {
                v = ((input[p] & 0xff) << 16) |
                    ((input[p+1] & 0xff) << 8) |
                    (input[p+2] & 0xff);
                output[op] = alphabet[(v >> 18) & 0x3f];
                output[op+1] = alphabet[(v >> 12) & 0x3f];
                output[op+2] = alphabet[(v >> 6) & 0x3f];
                output[op+3] = alphabet[v & 0x3f];
                p += 3;
                op += 4;
                if (--count == 0) {
                    if (do_cr) output[op++] = '\r';
                    output[op++] = '\n';
                    count = LINE_GROUPS;
                }
            }

            if (finish) {

                if (p-tailLen == len-1) {
                    int t = 0;
                    v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
                    tailLen -= t;
                    output[op++] = alphabet[(v >> 6) & 0x3f];
                    output[op++] = alphabet[v & 0x3f];
                    if (do_padding) {
                        output[op++] = '=';
                        output[op++] = '=';
                    }
                    if (do_newline) {
                        if (do_cr) output[op++] = '\r';
                        output[op++] = '\n';
                    }
                } else if (p-tailLen == len-2) {
                    int t = 0;
                    v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
                        (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
                    tailLen -= t;
                    output[op++] = alphabet[(v >> 12) & 0x3f];
                    output[op++] = alphabet[(v >> 6) & 0x3f];
                    output[op++] = alphabet[v & 0x3f];
                    if (do_padding) {
                        output[op++] = '=';
                    }
                    if (do_newline) {
                        if (do_cr) output[op++] = '\r';
                        output[op++] = '\n';
                    }
                } else if (do_newline && op > 0 && count != LINE_GROUPS) {
                    if (do_cr) output[op++] = '\r';
                    output[op++] = '\n';
                }

                assert tailLen == 0;
                assert p == len;
            } else {
                // Save the leftovers in tail to be consumed on the next
                // call to encodeInternal.

                if (p == len-1) {
                    tail[tailLen++] = input[p];
                } else if (p == len-2) {
                    tail[tailLen++] = input[p];
                    tail[tailLen++] = input[p+1];
                }
            }

            this.op = op;
            this.count = count;

            return true;
        }
    }

    private Base64() { }   // don't instantiate
}

2

ใช้ Java 8 -

    public static String encodeString(String plainString) {
        return  Base64.getEncoder().encodeToString(plainString.getBytes());
    }

    public static String decodeString(String encodedString) {
        byte[] bytes = Base64.getDecoder().decode(encodedString);
        return new String(bytes);
    }

2

คุณสามารถลองสิ่งนี้

byte[] data = Base64.getDecoder().decode(base64fileContent);

"Base64.getDecode ()" ส่งคืนตัวถอดรหัส Base64 ที่สามารถถอดรหัสได้ จากนั้นคุณต้องถอดรหัสอีกครั้งโดยใช้ ".decode ()"


0

ในโค้ดที่คอมไพล์ด้วย Java 7 แต่อาจทำงานในจาวาเวอร์ชันที่สูงกว่าดูเหมือนว่ามีประโยชน์ในการตรวจสอบการมีอยู่ของjava.util.Base64คลาสและใช้วิธีการที่ดีที่สุดสำหรับ JVM ที่กล่าวถึงในคำถามอื่น ๆ ที่นี่

ฉันใช้รหัสนี้:

private static final Method JAVA_UTIL_BASE64_GETENCODER;

static {
    Method getEncoderMethod;
    try {
        final Class<?> base64Class = Class.forName("java.util.Base64");
        getEncoderMethod = base64Class.getMethod("getEncoder");
    } catch (ClassNotFoundException | NoSuchMethodException e) {
        getEncoderMethod = null;
    }
    JAVA_UTIL_BASE64_GETENCODER = getEncoderMethod;
}

static String base64EncodeToString(String s) {
    final byte[] bytes = s.getBytes(StandardCharsets.ISO_8859_1);
    if (JAVA_UTIL_BASE64_GETENCODER == null) {
        // Java 7 and older // TODO: remove this branch after switching to Java 8
        return DatatypeConverter.printBase64Binary(bytes);
    } else {
        // Java 8 and newer
        try {
            final Object encoder = JAVA_UTIL_BASE64_GETENCODER.invoke(null);
            final Class<?> encoderClass = encoder.getClass();
            final Method encodeMethod = encoderClass.getMethod("encode", byte[].class);
            final byte[] encodedBytes = (byte[]) encodeMethod.invoke(encoder, bytes);
            return new String(encodedBytes);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new IllegalStateException(e);
        }
    }
}

0
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
/***
 * 
 * @author Vaquar khan
 * 
 *
 */
public class AES {

    private static SecretKeySpec secretKey;
    private static final String VK_secretKey = "VaquarKhan-secrate-key!!!!";
    private static byte[] key;

    /**
     * 
     * @param myKey
     */
    public static void setKey(String myKey) {
        MessageDigest sha = null;
        try {
            key = myKey.getBytes("UTF-8");
            sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16);
            secretKey = new SecretKeySpec(key, "AES");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
/**
 * encrypt
 * @param strToEncrypt
 * @param secret
 * @return
 */
    public static String encrypt(String strToEncrypt, String secret) {
        try {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
        } catch (Exception e) {
            System.out.println("Error while encrypting: " + e.toString());
        }
        return null;
    }
/**
 * decrypt
 * @param strToDecrypt
 * @param secret
 * @return
 */
    public static String decrypt(String strToDecrypt, String secret) {
        try {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
        } catch (Exception e) {
            System.out.println("Error while decrypting: " + e.toString());
        }
        return null;
    }

    public static void main(String[] args) {
        final String secretKey = VK_secretKey;
        String password = "VKhan@12";
        //
        String encryptedString = AES.encrypt(password, secretKey);
        String decryptedString = AES.decrypt(encryptedString, secretKey);
        //
        System.out.println(password);
        System.out.println(encryptedString);
        System.out.println(decryptedString);
    }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.