String der eigentlich eine Ansammlung von HEX zeichen ist in datei schreiben in Hex

Benni1000

Mitglied
Hallo,

Ich stehe derzeit vor einem Problem:
Es ist ein String gegeben z.b der:
Code:
89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000017352474200aece1ce900000006624b474400ff00ff00ffa0bda793000000097048597300000b1300000b1301009a9c180000000774494d4507dc04150f1918b85f01ea000000df4944415438cbed92bd4a03511085bfbb2ec8826c913411021104b11352a74a21081a024b88822cb749e34bf81c5bb9ef6027a40ab10a29851462611124902ecd36c7e22e5e17cb6d5238303073989f333f06103524a0a6ec41015b63035625032ba700ad3e8c3ee16e0b9dc4075f3cc2edc6c7fd34b642e5250468f8865a7dd4e8a2e4c3e3f73b749a22028f59a13f3b88cfe0f2056e1670d4f1f87c02e70f3058c261f357425aa0e8b8caa07d8dcc41951938ec6a864ec6ce4f0b14ae3248de218c2037f03a81de13c4cfae416eaa337fcd613d75f62a03f3ff897b50e01b63544f29c4b5c60a0000000049454e44ae426082

Das ist ein beliebiges File das von HEX ins CHAR format umgewandelt wurde.
Nur wie bekomme ich den als HEX wieder in eine datei zurück?
Ich habe schon einige variationen mit dem FileOutputStream ausprobiert aber das klappt nicht wirklich.
Hat einer von euch eine idee wie ich das ins HEX format zurückbekomme und es in eine Datei
schreiben kann so dass ein funkionierendes File rauskommt?
Die Dateiendung wird vom Benutzer angegeben.

Mfg Benni1000
 
Wenn ich das mache dann bekommen ich ein paar invalide zeichen zurück. (Kann gut sein muss es aber nicht 😛)
Hier ist mal mein ganzer Code:
Java:
package file2hex.hex2file;

import java.io.*;
import java.util.Scanner;

public class File2HexHex2File {
    private static byte[] chars = {'0', '1', '2', '3', '4', '5','6', '7', '8', '9', 'a', 'b','c', 'd', 'e', 'f' };
    public static void main(String[] args) throws FileNotFoundException, IOException {
        if(args.length>2) {
            String from = args[1],to = args[2];
            if(!new File(to).exists()) {
                new File(to).createNewFile();
            }
            if(args[0].equalsIgnoreCase("-hex")) {
                FileInputStream fis = new FileInputStream(new File(from));
                byte[] program = new byte[(int) new File(from).length()];
                fis.read(program);
                FileWriter fw = new FileWriter(new File(to));
                fw.write(encode(program));
                fw.close();
            }
            if(args[0].equalsIgnoreCase("-bin")) {
                if(!new File(to).exists()) {
                new File(to).createNewFile();
                }
                Scanner sc = new Scanner(new File(from));
                byte[] decodedData = decode(sc.nextLine());
                FileOutputStream fos = new FileOutputStream(new File(to));
                fos.write(decodedData);
                fos.close();
            }
        }
    }
    public static String encode(byte[] b) {
        StringBuilder s = new StringBuilder(2 * b.length);
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xff;
            s.append((char)chars[v >> 4]);
            s.append((char)chars[v & 0xf]);
        }
        return s.toString();
 }
   public static byte[] decode(String str) {
        char[] buffer = str.toCharArray();
        byte[] b = new byte[buffer.length/2];
        for(int i = 0; i<buffer.length/2;i++) {
            String s = ""+buffer[i]+buffer[i+1];
            b[i] = (byte) Integer.parseInt(s, 16);
        }
        return b;
    }
}
Das Problem ist das dass ganze mit Binärdateien funkionieren soll.

Mfg Benni1000
 
Ist klar, dass komische Zeichen rauskommen. 89 ist dezimal 137, ASCII ist nur 127 Zeichen lang. Da wäre es interessant, den Speichercode zu kennen.
 
Das, was das ursprünglich umgewandelt hat.

"0" ist als ASCII-Code 48, was im Hex 30 ist.
"A" ist ASCII 65 und Hex 41.
"z" ist ASCII 122 und Hex 7a.

Aber 89 Hex (erstes Zeichen in deiner Folge) ist 137. ASCII geht nur bis 127, deshalb muss ein anderes Charset wie z. B. UTF-8 genutzt worden sein.
 
Ich weiss nicht was für ein Zeichensatz verwendet wurde.
Sollte aber eigentlich egal sein oder? Ich will es ja nicht in Text umwandeln sondern
es 1 zu 1 in eine Binärdatei "schreiben".
Bei dem Oben geposteten Text handelt es sich um ein .png bild.
Decoden tut mein Programm richtig:


Mfg Benni1000
 
Zuletzt bearbeitet:
Tut mir leid, ich habe dich vollkommen falsch verstanden.

Java:
public class Hex {
	private static final File OUTPUT_FILE = new File("samefile.png");

public static void main(String[] args) throws IOException {
	String inputHex = "89504e4...";
	
	byte[] bytes = inputToByteArray(inputHex);
	writeBytes(bytes);
}

private static void writeBytes(byte[] bytes) {
	ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
	
	BufferedOutputStream bos = null;
	try {
		bos = new BufferedOutputStream(new FileOutputStream(OUTPUT_FILE));
		byte[] buffer = new byte[8 * 1024 * 1024];
		int len = 0;
		do {
			len = bais.read(buffer, 0, buffer.length);
			if(len != -1) {
				bos.write(buffer, 0, len);
			}
		} while(len != -1);
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		try {
			if(bos != null) {
				bos.flush();
				bos.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}	
}

private static byte[] inputToByteArray(String inputHex) {
	int size = inputHex.length();
	if(size % 2 != 0) {
		throw new IllegalArgumentException("input size%2 must be 0");
	}
	
	byte[] bytes = new byte[size / 2];		
	for(int i = 0; i < size; i+= 2) {
		char firstChar = inputHex.charAt(i);
		char secondChar = inputHex.charAt(i + 1);
		
		String hex = new String(String.valueOf(firstChar) + String.valueOf((char)secondChar));
		int intUnsigned = Integer.parseInt(hex, 16);
		bytes[i / 2] = (byte) (intUnsigned & 0xff);
	}
	return(bytes);
}

Die Schleife kann wahrscheinlich stark verbessert werden, aber ich spiele mich selbst nicht so oft mit Umwandlungen herum, deshalb kenn ich auf die Schnelle dafür keine Hilfsklassen etc.
 
Zuletzt bearbeitet:

Zurück
Oben