Verschlüsselung von Dateien

Status
Nicht offen für weitere Antworten.

TeKo

Mitglied
Moin,
Also ich möchte ne Datei mit XXTEA verschlüsseln, wenn ich die Datei einfach in ein Byte Array einlese, läuft alles.
Jetzt lese ich die Datei Stückweise ein und die Ausgabe ist einfach ca. 1kb kleiner als die Original Datei.

Was mache ich hier falsch?
Einlesen:
Code:
byte[] bytes = new byte[1024];

		int i = 0;
		int j = 0;

XXTEA xxtea = new XXTEA(); 
			while (j <= file.length()) {
				if (i < 1024 && i < file.length()) {
					bytes[i] = (byte) fis.read();
					i++;
					j++;
				} else {
					i = 0;
					fos.write(xxtea.encrypt(bytes,key));
				}
			}


Wenn ihr den TEA code braucht, bescheid sagen, aber ist halt einfach ne funktion, die nen Byte Array übergeben kriegt, dies dann in ein Int Array umwandelt, verschlüsselt und wieder als Byte Array ausgibt.
 
fos.write() wird nur bei i = 1024 durchgeführt,
wenn die Datei aber nur 950 lang ist oder zumindest der letzte Abschnitt der Datei nicht auf ganze 1024 kommt,
dann wird der letzte Teil nicht bearbeitet,

lasse dir den Wert i nach der while-Schleife ausgeben, um so viel wird die Datei kleiner sein,
du musst nach der while-Schleife je nach i-Stand den Rest bearbeiten

-----

Vorsicht mit tausend- oder millionenfachen Aufruf von file.length(),
mit etwas Pech ist da jedes Mal ein Dateizugriff nötig,

wenn du weißt, dass sich die Datei nicht ändert, dann speichere diesen Wert in einer Variablen,

genauso ist fis.read() einzeln ganz schön langsam, verwende lieber einen BufferedInputStream
und lies gleich tausende Bytes auf einmal ein, das spart evtl. auch Festplattenzugriffe

wenn du einen Buffer von 1024 nimmst, dann kannst du gleich die Schleife vereinfachen:
immer 1024 lesen und gleich speichern,
du wirst weiterhin das Problem haben, dass die Dateilänge nicht unbedingt genau durch 1024 teilbar ist, aber etwas einfacher wirds auch bei dieser Sache
 
Erstma Danke für die schnelle Antwort.

Den Teil mit der länge < 1024 habe ich doch damit:
Code:
if (i < 1024 && i < file.length())
abgefangen oder nicht?

Werde mir mal den BufferedIS angucken, habe bis jetzt wenig mit solchen Sachen gearbeitet.

Wegen den vielen aufrufen von file.length(), um sowas habe ich mich erstmal gar nicht gekümmert, ich wollte erstmal, dass es überhaupt funktioniert und dann kann ich gucken, wie ich es schneller oder Speicher schonender mache.[/code]
 
> if (i < 1024 && i < file.length())

kommt in 99,9% aller Schleifendurchläufe dran, ja, aber damit wird nur das Array beschrieben,

der EINE else-Fall mit dem
> fos.write(xxtea.encrypt(bytes,key));
ist doch viel interessanter, der fehlt und deswegen ist die Datei zu kurz

-----

"i < file.length()" könntest du im if gar weglassen, die while-Bedingung verhindert dies genauso

-------

vielleicht möchtest du eine Schleife
if (i < 1024 && (i+1) < file.length())

versuchs mal damit

allerdings musst du aufpassen, dass du keine Endlosschleife erhälst,
wenn immer in den else-Fall gesprungen wird, j sich nie erhöht,

außerdem darfst du nicht das ganze Array schreiben, es ist nur teilweise gefüllt
bzw. enthät, noch schlimmer, teilweise alte, nicht überschriebene, Daten
 
habe file.length() mal in nen int geschrieben, hattest wohl recht geht 100mal so schnell.

das mit dem (i+1) hat nichts verändert eine 1.272kb datei ist nur 1.271kb groß


Mit der Endlosschleife verstehe ich nicht ganz, ich möchte j ja auch nur ehöhen, wenn wirklich was in das Array geschriebenen wurde.

Aber jetzt weiß ich glaube ich, was mein Fehler war.
Wenn die Datei z.B. 1025 bytes hat, dann werden die ersten 1024 geschrieben, dann kommt das 1025te an Stelle 0 des Arrays, wird aber nicht mehr geschrieben, da i nicht 1024 ist.

Wie mache ich dass denn am besten mit dem nicht leeren Array, nach jedem schreiben neu initialisieren ist ja iwie nicht das wahre.

Aber ich müsste denke ich bei dem letzten Teil der Datei, welcher wohl nicht immer genau 1024 groß ist das Array kürzen und dann zum schreiben weiter geben.
 
stimmt, i+1 macht wenig sinn, da i eh ständig auf 0 gesetzt wird,
die Idee besser nicht weiter verfolgen,

-----

das einfachste wäre, alles so wie bisher zu lassen und am Ende nach der Schleife nochmal das verbleibende Array zu speichern,

was du an
xxtea.encrypt() übergeben kannst/ darfst/ musst/ solltest kann ich nicht beurteilen,
vielleicht kürzt du das Array, ja,
dann musst du auch nicht neuinitialisieren
 
Habe da mal gerade was zusammen geschmissen:
also wenn die länge- bis jetzt gelesene Bytes < 1024 ist, also das Array nicht voll werden würde.
wird ein neues Array erstellt, mit der länge der restlichen Zeichen, liest diese ein und schreibt sie.

Beim nochmal drüber gucken habe ich gesehen, das es ne endlos schleife geben müsste, wenn die länge durch 1024 teilbar ist, aber das lässt sich ja abfangen.
Oder doch nicht, da die Überprüfung ja i<1024 ist, also kommt er bei genau 1024 in den unteren Teil und beendet dann auch die endlosschleife.

Ist irgendwie murx, und ich habe das gleiche Problem wie vorher.

Code:
XXTEA xxtea = new XXTEA();
			while (true) {
				if (length-j > 1024) {
					if (i < 1024) {
						bytes[i] = (byte) fis.read();
						i++;
						j++;
					} else {
						i = 0;
						fos.write(xxtea.encrypt(bytes, key));
					}
				}
				else{
					byte[] bytes1 = new byte[length-j];
					while(j < length){
						bytes1[i] = (byte) fis.read();
						j++;
					}
					fos.write(xxtea.encrypt(bytes1, key));
					break;
				}
			}
 
stell dir vor, du hast eine 1600 bytes-Datei,
es wird 576x per Zeile 5 in das Array geschrieben und dann kommt Zeile 14 dran,
die restlichen 1024 Bytes werden übertragen, die ersten 576 aber ganz weggelassen,

so vermute ich das im Moment, mit System.out.println usw. zu testen,
logge zumindest jede Durchführung von Zeile 10 und Zeile 19

"schreibe nun 1024 Bytes in Zeile 10"
"schreibe nun 1024 Bytes in Zeile 10"
usw.

----

Lösung falls es das ist: der Test length-j > 1024 ist schlecht,
berechne vorher length % 1024 und dann genau den Index k, ab dem der Rest gesonder zu behandeln ist,
im 1600er Beispiel ist das 1024, ist immer ein Vielfaches von 1024,

lasse erst eine while-Schleife oder auch eine for-Schleife mit ganzen Arrays arbeiten,
dann ab Index k beginnt eine zweite Schleife, die sich um die restlichen Bytes kümmert
 
Boa steh echt aufem Schlauch 😉
Wenn man da die ganze Zeit draufguckt.

Also jetzt scheint es zu funktionieren:
Code:
XXTEA xxtea = new XXTEA();
			while (true) {
				if (length - j > 1024) {
					while (i < 1024) {
							bytes[i] = (byte) fis.read();
							i++;
							j++;
					}
					i = 0;
					fos.write(xxtea.encrypt(bytes, key));
				} else {
					byte[] bytes1 = new byte[length - j];
					while (j < length) {
						bytes1[i] = (byte) fis.read();
						j++;
					}
					fos.write(xxtea.encrypt(bytes1, key));
					break;
				}
			}

Werde decrypt jetzt auch mal so umbaun, dann sehen ich ja, ob alles richtig gelesen und geschrieben wurde.

Also die Datei wird gelesen, verschlüsselt geschrieben und dann wieder entschlüsselt, leider ist die .rar Datei dann nicht mehr lesbar 😉


EDIT: Habe jetzt einmal die Datei direkt schreiben lassen ohne verschlüsselung, da kommt, wenn ich die .rar öffne "Der Dateikopf ist beschädigt".
Da muss ich wohl nochmal genau gucken.


Danke für die Mühe, hast mir super geholfen.
Hatte bei dem letzten Code einfach bei dem 2ten j++ das i++ vergessen.
Läuft jetzt so auch mit der Verschlüsselung und allem.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben