Domanda

Ho bisogno di scrivere una stringa contenente testo codificato in base64 in un file di testo e successivamente rileggere quella stringa dal file di testo in una variabile stringa.

Come posso fare in modo che non ci siano perdite di dati dovute a problemi di codifica?

È stato utile?

Soluzione

Base64 è solo A & # 8211; Z, a & # 8211; z, 0 & # 8211 ; 9, + e /. Quindi non ci dovrebbero essere problemi di codifica. Finché sei in grado di codificare correttamente Ascii. Base64 è stato inventato per rappresentare byte in caratteri a 7 bit .

Per codificare e decodificare è possibile utilizzare commons codec Base64 .

Altri suggerimenti

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

Decodificatore 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 del codificatore 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

Ecco un codice semplice che codificherà e decodificherà:

Passaggi della codifica

  1. Codifica byte
  2. Converti byte codificati in stringa esadecimale

Passaggi di decodifica

  1. Converti stringa esadecimale in byte codificati
  2. Decodifica byte
  3. Converti byte decodificati in stringa esadecimale
  4. Converti stringa esadecimale in stringa di caratteri ASCII (stringa normale)

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

Esiste una classe solare che lo farà per te (anche se genererà avvisi del compilatore:

import sun.misc.BASE64Encoder;

BASE64Encoder encoder = new BASE64Encoder();

String toEncode = "encodeMe";

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

Dalla memoria, c'è anche un BASE64Decoder, ma non l'ho usato, vado solo in un modo per il confronto dei nomi utente over-the-wire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top