Java - Base64 字符串进出文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1802553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:48:11  来源:igfitidea点击:

Java - Base64 string in and out of a text

javaencodingbase64

提问by rover12

I need to write string containing base64 encoded text to a text file and then later read that string back from the text file to a string variable.

我需要将包含 base64 编码文本的字符串写入文本文件,然后将该字符串从文本文件读回字符串变量。

How can i do it so that there is no data loss due to encoding issues?

我该怎么做才能不因编码问题而丢失数据?

采纳答案by Thomas Jung

Base64is only A–Z, a–z, 0–9, + and /. So there should be no encoding problem. As long as you're able to encode Ascii properly. Base64 was invented to represent bytes in 7-bit characters.

Base64只是 A–Z、a–z、0–9、+ 和 /。所以应该没有编码问题。只要您能够正确编码 Ascii。Base64 被发明来用7 位字符来表示字节。

To encode and decode you can use commons codec Base64.

要编码和解码,您可以使用公共编解码器 Base64

回答by Sajad Bahmani

Base64 Encoder :

Base64 编码器:

// Sample program to encode a binary file into a Base64 text file.
// Author: Christian d'Heureuse (www.source-code.biz)

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;

public class Base64FileEncoder {

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

    private static void encodeFile (String inputFileName, String outputFileName) throws IOException {
        BufferedInputStream in = null;
        BufferedWriter out = null;
        try {
            in = new BufferedInputStream(new FileInputStream(inputFileName));
            out = new BufferedWriter(new FileWriter(outputFileName));
            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, len));
            out.newLine(); 
        }
    }

} // end class Base64FileEncoder

Base64 Decoder :

Base64 解码器:

// Sample program to decode a Base64 text file into a binary file.
// Author: Christian d'Heureuse (www.source-code.biz)

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;

public class Base64FileDecoder {

    public static void main (String args[]) throws IOException {
        if (args.length != 2) {
            System.out.println ("Command line parameters: inputFileName outputFileName");
            System.exit (9); 
        }

        decodeFile (args[0], args[1]); 
    }

    private static void decodeFile (String inputFileName, String outputFileName) throws IOException {
        BufferedReader in = null;
        BufferedOutputStream out = null;
        try {
            in = new BufferedReader(new FileReader(inputFileName));
            out = new BufferedOutputStream(new FileOutputStream(outputFileName));
            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.decode(s);
            out.write (buf); 
        }
    }

} // end class Base64FileDecoder

Test Base64 Coder :

测试 Base64 编码器:

// Test program for the Base64Coder class.

public class TestBase64Coder {

    public static void main (String args[]) throws Exception {
        System.out.println ("TestBase64Coder started");
        test1();
        test2();
        System.out.println ("TestBase64Coder completed"); 
    }

    // Test Base64Coder with constant strings.
    private static void test1() {
        System.out.println ("test1 started");
        check ("Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==");  // example from RFC 2617
        check ("", "");
        check ("1", "MQ==");
        check ("22", "MjI=");
        check ("333", "MzMz");
        check ("4444", "NDQ0NA==");
        check ("55555", "NTU1NTU=");
        check ("abc:def", "YWJjOmRlZg==");
        System.out.println ("test1 completed"); 
    }

    private static void check (String plainText, String base64Text) {
        String s1 = Base64Coder.encodeString(plainText);
        String s2 = Base64Coder.decodeString(base64Text);
        if (!s1.equals(base64Text) || !s2.equals(plainText))
            System.out.println ("check failed for \""+plainText+"\" / \""+base64Text+"\"."); 
    }

    // Test Base64Coder against sun.misc.BASE64Encoder/Decoder with
    // random strings.
    private static void test2() throws Exception {
        System.out.println ("test2 started");
        sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
        sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
        java.util.Random rnd = new java.util.Random(0x538afb92);

        for (int i = 0; i < 50000; i++) {
            int len = rnd.nextInt(55);
            byte[] b0 = new byte[len];
            rnd.nextBytes(b0);
            String e1 = new String(Base64Coder.encode(b0));
            String e2 = enc.encode(b0);
            if (!e1.equals(e2)) 
                System.out.println ("Error\ne1=" + e1 + " len=" + e1.length() + "\ne2=" + e2 + " len=" + e2.length());

            byte[] b1 = Base64Coder.decode(e1);
            byte[] b2 = dec.decodeBuffer(e2);
            if (!compareByteArrays(b1, b0) || !compareByteArrays(b2, b0))
                System.out.println ("Decoded data not equal. len1=" + b1.length + " len2=" + b2.length); 
        }

        System.out.println ("test2 completed"); 
    }

    // Compares two byte arrays.
    private static boolean compareByteArrays (byte[] a1, byte[] a2) {
        if (a1.length != a2.length) return false;
        for (int p = 0; p < a1.length; p++)
            if (a1[p] != a2[p]) return false;

        return true; 
    }

} // end class TestBase64Coder

回答by James B

There is a sun class that will do it for you (although it will generate compiler warnings:

有一个 sun 类可以为您完成(尽管它会生成编译器警告:

import sun.misc.BASE64Encoder;

BASE64Encoder encoder = new BASE64Encoder();

String toEncode = "encodeMe";

String encoded = encodeBuffer(toEncode.getBytes());

From memory, there's also a BASE64Decoder, but I've not used that, I only go one way for comparison of usernames over-the-wire.

从记忆中,还有一个 BASE64Decoder,但我没有使用过它,我只采用一种方法来在线比较用户名。

回答by Atyab

Here is a Simple Code which will Encode and Decode:

这是一个简单的代码,它将编码和解码:

Steps of Encoding

编码步骤

  1. Encode Bytes
  2. Convert Encoded Bytes to Hex String
  1. 编码字节
  2. 将编码字节转换为十六进制字符串

Steps of Decoding

解码步骤

  1. Convert Hex String to Encoded Bytes
  2. Decode Bytes
  3. Convert Decoded Bytes to Hex String
  4. Convert Hex String to ASCII Character String (Normal String)

    // Encoding Bytes
    byte[] b64ENC = Base64.encode("Hello World".getBytes("UTF-8"));
    String ENCStr = getHexString(b64ENC,b64ENC.length);
    T1.setText(ENCStr);  //-- for output
    
    // Decoding Bytes
    byte[] DECBarray = hexStringToByteArray(ENCStr);
    byte[] b64DEC = Base64.decode(DECBarray);
    
    // Displaying Decoded Byte Array by Converting it To String
    try {
        String ResDec = new String(b64DEC,"UTF-8");
        T2.setText(ResDec);   //This Displays Hello World :)
    
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    // Following are the functions that I used above !
    public String getHexString(byte[] b, int length) {
        // TODO Auto-generated method stub
        String result = "";
    
        for (int i = 0; i < length; i++) {
            result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring(1);
        }
        return result;
    }
    
    public static String bytesToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            buf.append(byteToHex(data[i]));
            buf.append(" ");
        }
        return (buf.toString());
    }
    
    public static String byteToHex(byte data) {
        StringBuffer buf = new StringBuffer();
        buf.append(toHexChar((data >>> 4) & 0x0F));
        buf.append(toHexChar(data & 0x0F));
        return buf.toString();
    }
    
    public static char toHexChar(int i) {
        if ((0 <= i) && (i <= 9)) {
            return (char) ('0' + i);
        } else {
            return (char) ('a' + (i - 10));
        }
    }
    
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
    
        return data;
    }
    
  1. 将十六进制字符串转换为编码字节
  2. 解码字节
  3. 将解码字节转换为十六进制字符串
  4. 将十六进制字符串转换为 ASCII 字符串(普通字符串)

    // Encoding Bytes
    byte[] b64ENC = Base64.encode("Hello World".getBytes("UTF-8"));
    String ENCStr = getHexString(b64ENC,b64ENC.length);
    T1.setText(ENCStr);  //-- for output
    
    // Decoding Bytes
    byte[] DECBarray = hexStringToByteArray(ENCStr);
    byte[] b64DEC = Base64.decode(DECBarray);
    
    // Displaying Decoded Byte Array by Converting it To String
    try {
        String ResDec = new String(b64DEC,"UTF-8");
        T2.setText(ResDec);   //This Displays Hello World :)
    
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    
    // Following are the functions that I used above !
    public String getHexString(byte[] b, int length) {
        // TODO Auto-generated method stub
        String result = "";
    
        for (int i = 0; i < length; i++) {
            result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring(1);
        }
        return result;
    }
    
    public static String bytesToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            buf.append(byteToHex(data[i]));
            buf.append(" ");
        }
        return (buf.toString());
    }
    
    public static String byteToHex(byte data) {
        StringBuffer buf = new StringBuffer();
        buf.append(toHexChar((data >>> 4) & 0x0F));
        buf.append(toHexChar(data & 0x0F));
        return buf.toString();
    }
    
    public static char toHexChar(int i) {
        if ((0 <= i) && (i <= 9)) {
            return (char) ('0' + i);
        } else {
            return (char) ('a' + (i - 10));
        }
    }
    
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
    
        return data;
    }