# byte.toString() -> Datenmüll



## AlexDozer (5. Jun 2008)

Hi,

ich lese mit Hilfe eines InputStreams eine Html-Seite in ein Byte-Array ein. 


```
byte [] bt = new byte[10000];
inputstream.read(bt);
```

Im Byte-Array steht jetzt der ganze Html-Code als Ascii-Code drin. Das funktioniert wunderbar. Nur wenn ich mir jetzt das ganze als String geben lassen möchte:


```
return bt.toString();
```

Bekomme ich diesen Datenmüll: *[B@ec16a4*

Jemand ne Idee warum?


Gruß Alex


----------



## Guest (6. Jun 2008)

Schon mal angeschaut was byte[]#toString() macht?


```
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
```

Und jetzt überleg mal wie da ein String mit HTML raus kommen soll.

Es gibt übrgigens für String einen Konstruktor den ich mir an deiner Stelle mal ansehen würde.


```
String s = new String(byte[]);
```


----------



## jansen (19. Mai 2010)

Hi Leute zur Frage von AlexDozer war ja schon alles gesagt.


ich habe jetzt aber folgendes Problem:

Gibt es zu dieser Methode  "byte[].toString" eine "Umkehroperation". ich such mich hier dumm und dämlich

schön wär eine Methode wie z.B. 
	
	
	
	





```
/*pseudo:*/ byte[] myBytes= mystring.tobyte[]();
```
oder 
	
	
	
	





```
/*pseudo:*/ byte[] myBytes= mystring.toByteArray();
```


-ich muss quasi einen alphanumerischen String aus einem byte[] aufbauen
-dieser String wird an einen Server gesendet, der daraus wieder ein byte[] machen muss
-die new String(byte[], "CharsetName") - Variante hat einen unleserlichen String erstellt, was aber für die Weiterverarbeitung unbedingt benötigt wird!
-mit der "byte[].toString"-Methode kann ich einen leserlichen String erstellen


habt ihr ne idee wie ich wieder zu meinen byte[] zurückkomme?


----------



## srea (19. Mai 2010)

```
byte[] myBytes = stringToConvert.getBytes();
```


Edit: Hatte zuerst übersehen, das es ein byte[]-Array ist -.-

BTW: 30sec google, string to byte


----------



## Ark (19. Mai 2010)

(Okay, ich bin etwas spät dran, aber ich poste trotzdem; ist ja auch ein Link enthalten.)

Suchst du vielleicht das hier? String (Java Platform SE 6)

Es wäre übrigens gut, sich über die String-Repräsentation in Java schlau zu machen, da ist nämlich nix mit Bytes und ASCII, sondern char und Unicode. Und die allgemein bekannte Zeichensatzproblematik würde ich mir auch mal zu Gemüte führen.

Ark


----------



## jansen (19. Mai 2010)

jo also wie gesagt :

die String.getBytes() - methode kann ich nicht verwenden!!!! ,

da ich einen "leserlichen" (alphanumerischen) String haben möchte
dies ist nicht der Fall, da das byte[] zuvor gezippt wurde

die einzige chance war die Methode .toString, die das byte[] in einen leserlich String wandelt

am besten bereite mal ein beispiel auf...


----------



## srea (19. Mai 2010)

Wo steht das du das nicht verwenden kannst? Und warum nicht?
Gehts jetzt drum den String zu bekommen oder ein byte[] Array aus einem String? Oo

Ich bin verwirrt!


----------



## jansen (19. Mai 2010)

Ablauf:

-string wird in byte[] gewandelt um diesen zu Zippen
-der gezippt String muss zurück in string geparsed werden,
 dabei muss der String Zeichen aus dem UTF8 format enthalten

[Problem] wandelt man das byte[] mittels:

string2transmit = new String(myzippedbytearray, "UTF8") 

um 

so erhält man nicht darstellbar Zeichen im String.

|---------------------------------------------------------

```
Bsp. mit String.getBytes():

Pseudo:

String str1  = "Ein unkomprimierter String"; 

byte[] bytes2compress = str1.getBytes("UTF8");

/* AUSGABE vor dem Zippen des byte[]

   bytes2compress:                     [B@e48e1b
   byte2compress.lenght:               26
   bytes2compress.toString:            [B@e48e1b
   
   new String(bytes2compress,"UTF8"):  Ein unkomprimierter String
    
*/

//Zippen des byte[]...

//...

byte[] compressedBytes //ergebnis des zip vorganges

/* AUSGABE nach dem Zippen des byte[]

   compressedBytes:                     [B@10385c1
   compressedBytes.lenght:               16             //bspw.
   compressedBytes.toString:            [B@10385c1
   
   new String(compressedBytes,"UTF8"):  x?VrU?RrLN-Rp??/H-J,????C // ?= schwarze Rauten mit ?
                                                                  // und ebenso diese allseitsbekannten leeren Quadrate
    
*/
```
->


----------



## jansen (19. Mai 2010)

ich möchte aus einem String ein byte[] machen

also diesen Ausdruck:


```
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
```

rückgängig machen- geht das den überhaupt? wenn ja gibt es dafür schon eine Methode?

EDIT:

@srea war natürlich schmarrn was Ich da geschrieben habe natürlich benutze ich die getBytes()- methode
ich meinte die die gegenoperation der getBytes()-methode



EDIT2:
vielleicht drück ich mich zu undeutlich aus!?


----------



## Gastredner (19. Mai 2010)

Bevor du aus deinem gezippten byte[] wieder einen String machen kannst, musst du es wieder entzippen. Danach sollte der Stringkonstruktor [c]String(byte[])[/c] auch wieder ein sinnvolles Ergebnis erzeugen.

EDIT: Warum überhaupt das byte[]-Gehampel? Wenn du einfach nur Strings an einen Server senden willst, dann könntest du doch auch einen ObjectOutputStream in deinem Client bzw. einen ObjectInputStream in deinem Server verwenden.


----------



## Ark (19. Mai 2010)

Gegenfrage, weißt du eigentlich, was beim Komprimieren prinzipiell geschieht? Wenn ja, sollte dir auch eigentlich klar sein, warum du den Datenstrom erst einmal wieder dekomprimieren musst.

Worauf du hinaus willst, ist mir aber trotzdem schleierhaft ... Wozu überhaupt die Kompression?

Ark


----------



## Gast2 (19. Mai 2010)

jansen hat gesagt.:


> ich möchte aus einem String ein byte[] machen
> 
> also diesen Ausdruck:
> 
> ...


Ich glaube du verwechselst da immer noch was. Die Methode toString() wandelt dir dein byte-array nicht in den String um der in deinem byte-array steht. Umformen von toString() zu byte[] macht in meinen augen also wenig sinn ???:L

Evtl. ist das ja was du suchst:


```
String test = "TestXtring";
        
        // mache irgendwas mit den Bytes:
        byte[] bytes = test.getBytes();
        bytes[4] = 115;

        String neuerTestString = new String(bytes);
        System.out.println(neuerTestString); // (Ausgabe: Teststring)
```


----------



## jansen (19. Mai 2010)

also:

mir ist bewusst, dass nach dem komprimieren, die Daten verwurschtelt werden

mein hauptproblem ist folgendes:

-ich habe einen sehr großen string
-dieser soll mit einem speziellem verfahren encodiert werden
-da der daraus entstandene QRCode sollte eine maximale Größe nicht überschreiten -(Anwendungsabhängig)

-ergo muss ich die zu codierenden Daten Synthaktisch verkleinern, der Informationsgehalt muss dabei erhalten beliben
- da der algorithmus nur alphanumerische Strings encoded, müsste ich doch den String so komprimieren
, dass dieser ebenso alphanumerisch ist

-einen String direkt zu zippen funktioniert mit den vorhandenen Libaries nicht
deshalb der umweg über byte[] (was ja auch völlig klar ist)

mein problem ist nicht der zippvorgang 
mein problem ist einen komprimierten string im utf8 format zu erhalten


----------



## jansen (19. Mai 2010)

@ eikB schau doch mal in mein BSP codezeile 31
das was du mir vorschlägst ist mein eigentliches prob


----------



## Ark (19. Mai 2010)

Noch mal:

Du hast einen String. (Stimmt das? Ist das wirklich kein Byte-Array, das du da hast?)
Dieser muss komprimiert werden. (Ja?)
Das Kompressionsergebnis muss wieder in einen Container (Ja?), und dieser Container kann nur ein String sein (Ja?), und dieser String darf nur [ASCII-Zeichen? Unicode-Zeichen? Mit/ohne Steuerzeichen?] enthalten.
Dieser String muss anschließend wieder wo hin. (Ja, wohin eigentlich?)

Ark


----------



## jansen (19. Mai 2010)

largeString->byte[]->compressedbyte[]~~~~>compressedString->Verarbeitung durch "QR-Code-Creator"

QRCODE= ist in sich stimmig


QRcode wird eingelesen->compressedString~~~~>compressedbyte[]->decompressedbyte[]->decompressedLargeString

EDIT: das sind die Schritte vielleicht gibt es noch eine andere möglichkeit den string zu komprimieren

wäre der string nicht zu groß würde sich folgendes flussdiagramm(wenn mans so nennen darf) ergeben:

string->Verarbeitung durch "QR-Code-Creator"-> QRcode

QRCode = in sich stimmg

qrcode wird eingelesen->string->weitere Auswertung


----------



## Gast2 (19. Mai 2010)

Kannst du deinen largeString nicht in viele kleine substrings zerlegen, diese dann einzeln durch den "QR-Code-Creator" schicken und danach wieder zusammensetzen? (Weiß grad nicht wie der algo funktioniert und ob das so überhaupt möglich ist...)


----------



## Ark (19. Mai 2010)

Hm, ich weiß zwar nicht, wie festgenagelt diese Verarbeitung ist, aber:

Was bitte ist ein compressedString?

Was erwartet der "QR-Code-Creator"? Einen java.lang.String? Oder Bytes? Oder ASCII-Zeichen? Oder Unicode-Zeichen? Nimmt er jeden beliebigen String, oder muss dieser String einen bestimmten Aufbau haben? Gibt es eine Längenbeschränkung für den String?

Bist du dir sicher, dass der "QR-Code-Creator" richtige Ergebnisse liefern kann, wenn ein "compressedString" eingegeben wird?

Warum geschieht die Kompression/Dekompression mittendrin und nicht ganz am Ende bzw. Anfang der Verarbeitung?

Ark


----------



## jansen (19. Mai 2010)

um auf deine fragen zu antworten ARK:
alles richtig verstanden
die UTF8 codierung umfasst ja ASCII- sowie Unicode-zeichensatz
es soll aber nur der Ascii-zeichensatzt genommen werden (eigentlich nur Zahlen und Buchstaben)

wenn man sich das compressedByte[] wertemäßig anschaut kommen auch negative Werte Integer raus
in der UTF8-Tabelle wären das Werte am ende der Tabelle - also nicht Ascii zeichen
steuerzeichen werden von der Anwendung erkannt und ausgewertet


----------



## Ark (19. Mai 2010)

Ich hoffe, du hast dir auch die Fragen hier durchgelesen. 

Und dann noch: Zeig doch mal konkrete Aufrufe von Methoden dieses "QR-Code-Creator"s. Oder besser: Zeige, wie bisher der Code aussieht, den du ändern willst.

Weißt du, warum die byte-Werte auch negativ sein können? Und wie man sie (bitgenau) gleichwertig positiv macht? Und was das überhaupt bedeutet, wenn ein byte[] einen UTF-8-Datenstrom repräsentiert?

Ark


----------



## jansen (19. Mai 2010)

@eikeB:
nein das wäre unnützt , so hätte man für jeden substring einen eigenen qrcode(2-d-matrixcode)

@ark:

<<<<<Was bitte ist ein compressedString?>>>>>

- compressedString habe ich jetzt einfach mal den komprimierten string genannt 



<<<<<
Was erwartet der "QR-Code-Creator"? Einen java.lang.String? Oder Bytes? Oder ASCII-Zeichen? Oder Unicode-Zeichen? Nimmt er jeden beliebigen String, oder muss dieser String einen bestimmten Aufbau haben? Gibt es eine Längenbeschränkung für den String?
>>>>>

Ich fang von hinten an. Ja die Längenbeschränkung ist die folgende:

Zeichensätze                                  Begrenzung
--------------------------------------------------
numerisch                                       max 1156 ziffern
alphaNum                                        max 698 zeichen
ISO (Latin und Kana)                         max 492 Bytes
Kanji                                              max 270 Worte (16 Bit)

-die obergrenzen werden nie überschritten- der eigentlich qrcode kann also erstellt werden
- das gerät , welches den code erfasst hat jedoch eine begrenzte aufnahmefähigkeit 
- 145 codierte zeichen sind zuviel die hälfte wäre besser 
mit dem zip-algo würde ich auf ca 85 zeichen kommen

der qr-creator braucht einen JAVA.lang.String - das ist richtig


<<<<<<<<<
Bist du dir sicher, dass der "QR-Code-Creator" richtige Ergebnisse liefern kann, wenn ein "compressedString" eingegeben wird?
>>>>>>>>>

solange der compressedString: alphanumerisch ist (wie ich jetzt schon dieses Wort hasse^^)
schlägt die Encodierung nicht fehl
erlaubte zeichen: 0-9, A-Z, a-z, $*%+-./:]+

<<<<<<<<<<<
Warum geschieht die Kompression/Dekompression mittendrin und nicht ganz am Ende bzw. Anfang der Verarbeitung?
>>>>>>>>>>>

die Kompression geschieht doch am anfang!
und die dekompression am ende dieses großen zyklus


----------



## jansen (19. Mai 2010)

alles was du wissen musst,ist dass der string als parameter übergeben wird- den QR-creator selber stelle ich hier ganz bestimmt nicht rein, weil das nicht auf meinen mist gewachsen ist

und ja ich weiß warum die werte negativ werden - hängt ja vom zip-algo ab
und an den byte values werde ich ganz bestimmt nichts verändern
ich finde es auch nett, dass du mich mit anregenden fragen zur lösung bringen willst aber ich glaube 
ich muss mir da was anderes einfallen lassen
denn so komm ich nicht weiter


----------



## Gastredner (19. Mai 2010)

Kannst du auch Gleichheitszeichen verwenden? Wenn ja: Base64 ? Wikipedia
Damit kannst du aus deinem komprimierten byte[] einen ASCII-String erstellen. Java bietet auch Klassen zum BASE64-Enkodieren und -Dekodieren, allerdings liegen diese innerhalb eines sun-packages.

Wenn du kein = nutzen kannst, ersetze es vielleicht einfach durch ein anderes, vom BASE-Algorithmus nicht benutztes Zeichen und ersetze dieses wiederum durch das =, bevor du den String dekodierst.

EDIT: Ich Dummerchen - ich habe vergessen, dass du nur wenig Platz zur Verfügung hast. BASE64 erhöht den Platzverbrauch, da wird auch das Zippen nicht mehr viel helfen. Vielleicht findest du ja einen anderen Algorithmus.


----------



## jansen (19. Mai 2010)

ja bei base64 war ich auch schon- 
aber moment mal
der zip-algo arbeitet ja so, dass er sich wiederholende zeichen zählt und zusammenfügt
eventuell erhöht sich dann die kompressionsrate
obwohl, es werden dabei aus 3byte 4byte gemacht, wenn mir nichts anderes einfällt kann man das immer noch ausprobieren 
trotzdem danke für deinen tipp!


----------



## Ark (19. Mai 2010)

Ja, Base64 war auch mein erster Gedanke. Dennoch ein paar Anmerkungen:

Das bytes negativ sind, liegt nicht am Kompressionsalgorithmus, sondern an der Interpretation der 8 Bits (Zweierkomplement).

Wenn das Ding auch mit Kana und Kanji (für alle anderen: Japanisch) umgehen kann, warum sollten dann nur "0-9, A-Z, a-z, $*%+-./:]+" erlaubt sein? (Oder verwechsle ich da gerade etwas?)

Wenn die Datenmenge ein Problem ist, auf dass du zu Kompressionsalgorithmen greifen musst: Dir ist bewusst, dass es zu jedem beliebigen (verlustfreien) Kompressionsalgorithmus mindestens eine Eingabe/Bitfolge gibt, die durch diesen Algorithmus nicht weiter komprimiert werden kann?

Ein besserer Kompressionsalgorithmus wäre übrigens wahrscheinlich der Huffman-Code, aber das nur am Rande; die gerade genannte Beschränkung gilt ja trotzdem.

EDIT: Die Wahrscheinlichkeit, dass sich Zeichen in "normalen" Texten unmittelbar wiederholen, ist extrem gering, bei Kanji kommt sie so gut wie nie vor. (Gerade bei Kanji würde man an der Stelle eher auf das (stimmhafte) Wiederholungszeichen stoßen.)

Ark


----------



## jansen (19. Mai 2010)

also das mit der zeichen beschränkung war so gemeint:

im allgemeinen kann der qrcode die auf der 1. seite dieses threads genannten zeichensätze aufnehmen
in meinen anwendungsfall wird aber nur der alphanumerische zeichensatz genutzt
(kanji und kana hab ich zu vergleichzwecken hinzugeschrieben, dies sollte verdeutlichen, dass die datenkomprimierung nicht auf den qr-code zurückzuführen ist)

an den huffman habe ich auch schon gedacht - wenn es dafür fertige libaries gibt schön und gut
wenn ich den jedoch noch selber implementieren müsste, würde das meinen zeitrahmen vollkommen sprengen

ps: keiner hat etwas von normalen texten erzählt: 
es ging lediglich um die zeichen, ich habe kein wort über häufigkeit des auftretens der zeichen verloren
das leserlich habe ich auf den synthax bezogen und nicht auf die semantik - sorry wenn das so interpretiert wurde


----------



## jansen (19. Mai 2010)

Vielleicht kurze zwischen frage:

was macht denn überhaupt byte[].toString

erstellt diese Methode eine eindeutige Zuordnung zwischen Byte[] und den daraus resultierenden String?

Edit: 

also byte[mit bestimmten werten] => [B@10385c1
darausfolgt
[B@10385c1 => byte[mit den bestimmten werten]

oder kann man den weg zurück nicht finden?

wahrscheinlich weiß keiner was ich hier machen möchte


----------



## Ark (19. Mai 2010)

Du kannst dir byte[] wie eine eigene Klasse vorstellen, wobei aber insbesondere die Methode toString() nicht(!) überschrieben wurde und demzufolge das macht, was in Object.toString() gemacht wird: ein String zurückgegeben, der den Namen der Klasse und den Hashwert zurückgibt, mehr nicht. Das ist also 100%ig etwas, das du nicht gebrauchen wirst.

Wegen Kompression: Das Paket java.util.zip hält einige eventuell interessante Klassen bereit.

*EDIT:* Dass hier kaum einer versteht, was du willst, könnte vor allem daran liegen, dass du bisher noch keinen ganz konkreten Code gezeigt hast. Du musst diesen "QR-Code-Creator" nicht posten, aber die Aufrufe wären interessant.

*EDIT2:* Warum heißt es an einer Stelle, Steuerzeichen wären erlaubt, und an anderer Stelle wieder, man dürfe nur dieunddie Zeichen (aber keine Steuerzeichen) eingeben?

Ark


----------



## jansen (19. Mai 2010)

ok ich schau mal was ich an Code hier zusammen bekomme

das Package "java.util.zip" benutze ich doch schon die ganze Zeit
ich war auch der festen Annahme, dass es sich um ein Konvertierungsproblem handelt


imports:


```
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
```

zip-Methode:


```
/**
     * Compress data.
     * @param bytesToCompress is the byte array to compress.
     * @return a compressed byte array.
     * @throws java.io.IOException
     */
    private static byte[] Compress(byte[] bytesToCompress) throws IOException
    {
        // Compressor with highest level of compression.
        Deflater compressor = new Deflater(Deflater.BEST_COMPRESSION);
        compressor.setInput(bytesToCompress); // Give the compressor the data to compress.
        compressor.finish();
 
        // Create an expandable byte array to hold the compressed data.
        // It is not necessary that the compressed data will be smaller than
        // the uncompressed data.
        ByteArrayOutputStream bos = new ByteArrayOutputStream(bytesToCompress.length);
 
        // Compress the data
        byte[] buf = new byte[bytesToCompress.length + 100];
        while (!compressor.finished())
        {
            bos.write(buf, 0, compressor.deflate(buf));
        }
 
        bos.close();
 
        // Get the compressed data
        return bos.toByteArray();
    }
```

unzip-Methode:


```
/**
     * Decompress data.
     * @param compressedBytes is the compressed byte array.
     * @return decompressed byte array.
     * @throws java.io.IOException
     * @throws java.util.zip.DataFormatException
     */
    private static byte[] Decompress(byte[] compressedBytes) throws IOException, DataFormatException
    {
        // Initialize decompressor.
        Inflater decompressor = new Inflater();
        decompressor.setInput(compressedBytes);  // Give the decompressor the data to decompress.
        decompressor.finished();
 
        // Create an expandable byte array to hold the decompressed data.
        // It is not necessary that the decompressed data will be larger than
        // the compressed data.
        ByteArrayOutputStream bos = new ByteArrayOutputStream(compressedBytes.length);
 
        // Decompress the data
        byte[] buf = new byte[compressedBytes.length + 100];
        while (!decompressor.finished())
        {
            bos.write(buf, 0, decompressor.inflate(buf));
        }
 
        bos.close();
 
        // Get the decompressed data.
        return bos.toByteArray();
    }
```


TestMAIN:


```
public static void main(String[] args) {

		/*
		 * Charset-Standards:
		 * 
		 * 	Charset		Description
		 * 
		 *	US-ASCII	Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
		 *	ISO-8859-1  ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
		 *	UTF-8		Eight-bit UCS Transformation Format
		 *	UTF-16BE	Sixteen-bit UCS Transformation Format, big-endian byte order
		 *	UTF-16LE	Sixteen-bit UCS Transformation Format, little-endian byte order
		 *	UTF-16		Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark
		 * 
		 * */
		
		
		//String der encodiert werden soll 
        String str1 = new String("{\"E\":\"Acer Cooperation...........\",\"B\":\"111111111,11\",\"K\":\"0123456789\",\"BL\":\"80080080\"," +
				  				 "\"V\":\"eeeeeeeeeeeeegggggggggggaaaaaaaaaallll................\"}");
		
		
//******************************************************************************************************************************
//==============================================================================================================================
//******************************************************************************************************************************
     
		 	//ZipVariante 1
        	byte[] byte2compress = str1.getBytes(Charset.forName("UTF8"));
        	byte[] compressedBytes = NULL;
        	        	
        		//Ausgangssituation
				System.out.println("Ausgangssituation:\n=============================================================");
		        System.out.println("string:\n" + str1);
		        System.out.println("string.lenght: " + str1.length());
				System.out.println("\nbyte[]: " + byte2compress);
		        System.out.println("byte[].lenght: " + byte2compress.length);
		        System.out.println("byte[].toString: " + byte2compress.toString());
		        for(int i=0;i < byte2compress.length;i++){System.out.print(" " + byte2compress[i]);}
		       
		        //zippen
		        try 
		        {
		        	compressedBytes = Compress(byte2compress);
				} catch (IOException e) {e.printStackTrace();}
		        
		        System.out.println("\n\nNach Komprimierung Variante 1:\n=============================================================");		
		        //System.out.println("string:\n" + new String(compressedBytes,Charset.forName("UTF8")));
		        System.out.println("string:" + new String(compressedBytes.toString()));
		        System.out.println("string.length: " + String.valueOf(compressedBytes.length));
		        System.out.println("\nbyte[]: " + compressedBytes);
		        System.out.println("byte[].lenght: " + compressedBytes.length);
		        System.out.println("byte[].toString: " + compressedBytes.toString());
		        for(int i=0;i < compressedBytes.length;i++){System.out.print(" " + compressedBytes[i]);}
		    //_________________________________________________________________________________________
		        //byte to string
		        String string2transmit = compressedBytes.toString();
		    //----------------------------------BEIM-SERVER--------------------------------------------
		    byte[] decompressedBytes = NULL;
		   /*
		    byte[] receivedBytes = NULL;
		    
		    	
		    	//set received Bytes from transmitted String
		    	//~> "byte[] receivedBytes= string2transmit.toByte[]"
	
		    char[] helpingCharArray= string2transmit.toCharArray();
		    
		    	receivedBytes = new byte[helpingCharArray.length];
		    	
		    	for(int j=0; j < helpingCharArray.length; j++)
		    	{
		    		receivedBytes[j]=(byte) helpingCharArray[j];
		    	}
		    	
*/
		    
		        //unzippen
				try 
				{
					decompressedBytes = Decompress(/*receivedBytes*/compressedBytes);
					//decompressedBytes = Decompress((byte[])compressedBytes.toString());		
				} catch (IOException e) {e.printStackTrace();
				} catch (DataFormatException e) {e.printStackTrace();}
				
				String str2 = new String(decompressedBytes);
				
				System.out.println("\n\nDekomprimierung Variante 1:\n=============================================================");
		        System.out.println("string:\n" + str2);
				System.out.println("\nbyte[]: " + str2.getBytes(Charset.forName("ISO-8859-1")));
		        System.out.println("stringLenght: " + str2.length());}
```


----------



## Ark (19. Mai 2010)

Hm, dem Code nach zu urteilen, den ich da sehe, sollte es eigentlich reichen, nach der Kompression Folgendes zu tun:

```
byte[] komprimiert = ...;

StringBuilder ergebnis=new StringBuilder(komprimiert.length);
for(int i=0;i<komprimiert.length;i++){
	ergebnis.append((char)komprimiert[i]);
}

String zurWeiterverarbeitung = ergebnis.toString();
```
[c]zurWeiterverarbeitung[/c] solltest du dann in das Ding eingeben können, _vermute ich mal_. Ganz geheuer ist mir das aber nicht.

Ark


----------



## jansen (20. Mai 2010)

erstmal danke für deine Idee 
ich probiers gleich mal aus

Edit:

Schade hat nicht geklappt 
aber einen Versuch war es wert
der komprimierte String besitzt an vielen Stellen immer noch Zeichen, die nicht vom QR-Algorithmus erfasst werden


----------



## Ark (20. Mai 2010)

Tja, dann wird's kompliziert: Welche Zeichen werden denn angenommen? Du hast zwar schon mal das angedeutet, aber ich bin mir nicht sicher, ob ich das richtig gelesen habe. Gib doch deswegen mal alle zur Verfügung stehenden Zeichen einzeln an. Wenn du das gemacht hast, muss man dann die Anzahl dieser Zeichen zählen.

Je nachdem, was dann da für eine Zahl rauskommt, kannst/musst du dich zwischen Geschwindigkeit und Speicherplatzverbrauch entscheiden.  Hinweis: Je mehr Zeichen du findest, desto besser steht es um den Speicherverbrauch.

Ark


----------



## jansen (20. Mai 2010)

jetzt werde ich etwas konkreter:

also wir haben im worstCäse: 115 
Zeichenvorrat: [a-z $*%+-./:] und [0-9]+ 
(die eckigen Klammern zählen nicht dazu und das + hinter [0-9] bedeutet auch mehrmals möglich )
Steuerzeichen werden ebenso encodiert

ein QRCode mit 115 Zeichen ist schon eher einer von der großen Sorte
die Hälfte wäre angenehmer so um die ~ 50 Zeichen

das Zip-verfahren aus dem "java.lang.zip" Package ist eher ungeeignet, da logischer Weise der Zeichenvorratsbereich des komprimierten Strings überschritten wird 
(bzw. zum interpretieren der bytes nicht ausreicht)

was gibt es denn noch für Komprimierungsverfahren?

- Lempel -Ziv-Welch Verfahren (LZW)
- Huffmann-Kodierung
- Lauflängenkodierung
- Arithmetische Kodierung

kennt jemand noch welche, die für Texte geeignet sind?
ich suche der Zeit,ob schon einige dieser Verfahren implementiert sind und in diversen Libaries vorliegen
Vielleicht kennt ihr schon welche?

Edit:
ich würde mehr Wert auf geringen Speicherverbrauch legen!


----------



## Ark (20. Mai 2010)

jansen hat gesagt.:


> also wir haben im worstCäse: 115


D.h., jede erlaubte Eingabe ist höchstens 115 Zeichen lang!?



jansen hat gesagt.:


> Zeichenvorrat: [a-z $*%+-./:] und [0-9]+
> (die eckigen Klammern zählen nicht dazu und das + hinter [0-9] bedeuted auch mehrmals möglich )
> Steuerzeichen werden ebenso encodiert


Heißt das, man muss sich zwischen a-z (und blubb) und 0-9 entscheiden, oder kann man auch a-z mit 0-9 mischen?

Folgende Zeichen sind also erlaubt (ob Vereinigen der beiden Mengen möglich ist, habe ich gerade gefragt):

```
abcdefghijklmnopqrstuvwxyz$*%+-./:
0123456789
```
Was ist mit dem Leerzeichen?
Was ist mit Großbuchstaben?
Und welche Steuerzeichen werden denn zugelassen? Alle 0x00 bis 0x1F? Mehr? Weniger?



jansen hat gesagt.:


> ein qrcode mit 115 zeichen ist schon eher einer von der großen sorte
> die Hälfte wäre angenehmer so um die ~ 50 zeichen


Was denn nun, willst du viel übertragen können oder nicht? Wie schon oben erwähnt, gibt es eine Grenze (maximale Entropie), man kann nicht beliebig stark komprimieren. Es ist überhaupt schon verwunderlich, dass überhaupt Datenmengen erzeugt werden, die in so ein Ding rein sollen, das gar nicht für diese Datenmengen ausgelegt ist.



jansen hat gesagt.:


> das zip verfahren aus dem java.lang.zip package ist eher ungeeignet da logischer weise der zeichenvorratsbereich des komprimierten strings überschritten wird (bzw. zum interpretieren der bytes nicht ausreicht)


Vorsicht: Komprimiert und dekomprimiert werden Bytes, keine Zeichen! Es gibt zwar eine Zuordnung zwischen Bytes und Zeichen, nämlich den Zeichensatz, aber dir sollte bewusst sein, dass das alles völlig verschiedene Dinge sind.



jansen hat gesagt.:


> was gibt es denn noch für komprimierungsverfahren?
> 
> - Lempel -Ziv-Welch Verfahren (LZW)
> - Huffmann-Kodierung
> ...


Der Deflate-Algorithmus, der in java.util.zip zum Einsatz kommt, benutzt bereits Huffman und andere. Besser sind vielleicht noch die arithmetische Kodierung bzw. 7z/LZMA. (Lizenzsachen mal außer Acht gelassen, sofern es da irgendwie Probleme geben könnte; weiß ich gerade nicht.) Was machst du denn, wenn du trotz Komprimierung zu viele Daten erzeugst?



jansen hat gesagt.:


> Edit:
> ich würde mehr wert auf geringen Speicherverbrauch legen!


Mein Vorschlag: Rechne mal nach, ob du das 4/3-fache an Daten (nach der Komprimierung) vertragen kannst. Wenn ja, reicht Base64 aus (vorausgesetzt, wir kriegen irgendwie 64 bis 65 Zeichen im Zeichenvorrat zusammen).

Ark


----------



## jansen (20. Mai 2010)

1. richtig so war es gemeint, maximal kann der unstrukturierte string 115 zeichen lang sein
dazu: schöner wär ein JSON-string der bräuchte dann 147 Zeichen maximal

2. der string ist quasi aus dem Zeichenvorrat zusammengesetzt, also ja zahlen und buchstaben sind vereinbar

3. leerzeichen war mit in der menge enthalten (zwischen "z" und "$")

4. großbuchstaben sind eher ungünstig, da dadurch der code aufgebläht wird
dazu: die eingabe wird so realisiert, das wirklich nur solche zeichen (wie im vorrat) angenommen werden
wird also der string komprimiert sollten auch nur zeichen aus diesem vorrat enthalten sein

5. unter steuerzeichen meine ich dann sowas wie: \n \t \" (mehr wird eigentlich nicht gebraucht, meine ich)

6. nein, die datenmengen passen allemal in den QRCode, die spezielle anwendung erfordert nur weniger
dazu: der qrcode wird ja an einer stelle eingelesen , d.h. aufgenommen und decodiert
performanter weise sollte der code nicht unnötig groß sein, deswegen die beschränkung auf "50 zeichen" anstelle von "115 zeichen"

der code wird mühelos generiert , nur lassen sich solche "datenmengen" nur schlecht vom otto-normalen- standard-gerät schlecht einlesen

fakt ist: ich möchte einen string auf die hälfte schrumpfen lassen, aus performancegründen

7. ja mir ist bewusst, dass byte[] komprimiert werden, wie soll es denn sonst funktionieren

8. ok 7z/LZMA hab ich dann auch noch endeckt, aber wird nur das gleiche in grün sein

9.base64 haben wir doch schon ausgeschlossen!
ich weiß jetzt auch nicht warum du (ich dutze dich jetzt einfach mal) aufeinmal den string wieder größer machen willst
- möchtest du mich ärgern^^
nochmal mein Hauptziel:
mache GROß-String zu kleinString


----------



## Ark (20. Mai 2010)

jansen hat gesagt.:


> 1. richtig so war es gemeint, maximal kann der unstrukturierte string 115 zeichen lang sein
> dazu: schöner wär ein JSON-string der bräuchte dann 147 Zeichen maximal


Verstehe ich das richtig: Der Zeichenvorrat ist durch die Spezifikation für Zeichenketten in JSON beschränkt? Und weiter: Das, was benötigt wird, ist eine in JSON gültige Zeichenkette? Muss die 115-Zeichen-Begrenzung eingehalten, _bevor_ in gültige JSON-Zeichenketten kodiert wird, oder dürfen es nicht mehr als 115 Zeichen sein, _nachdem_ in JSON kodiert wurde?

Die Frage stelle ich, weil davon abhängt, welche Zeichen nun wie kodiert werden müssen und welche Zeichen sich eignen (und welche nicht).

Gibt es eigentlich noch mehr Beschränkungen/Kodierungen/Abhängigkeiten/etc., von denen hier noch nichts gesagt wurde?



jansen hat gesagt.:


> 2. der string ist quasi aus dem Zeichenvorrat zusammengesetzt, also ja zahlen und buchstaben sind vereinbar
> 
> 3. leerzeichen war mit in der menge enthalten (zwischen "z" und "$")


Okay, dann stellt sich das für mich gerade so dar:

```
abcdefghijklmnopqrstuvwxyz $*%+-./:0123456789
```
45 Zeichen, das ist schlecht.



jansen hat gesagt.:


> 4. großbuchstaben sind eher ungünstig, da dadurch der code aufgebläht wird
> dazu: die eingabe wird so realisiert, das wirklich nur solche zeichen (wie im vorrat) angenommen werden
> wird also der string komprimiert sollten auch nur zeichen aus diesem vorrat enthalten sein


Was heißt das denn jetzt wieder, dass durch Großbuchstaben Code aufgebläht wird? Warum? Und was für ein Code überhaupt?


Eine dringende Bitte: Stell die gesamte "Verarbeitungspipeline" dar: Was für Daten stehen am Anfang und wie sind sie kodiert? In welche Maschine gehen diese Daten? Was macht die Maschine mit den Daten? Wie ist die Ausgabe dieser Maschine kodiert? Wohin gehen dann die so kodierten Daten als nächstes (welche Maschine)? Was macht diese Maschine mit den Daten? usw. usf. Wichtig ist dabei vor allem, dass du jeweils die Kodierung der Daten angibst. Langsam blicke ich nämlich nicht mehr durch, welche Daten jetzt wie kodiert woher kommen und wohin gehen.




jansen hat gesagt.:


> 5. unter steuerzeichen meine ich dann sowas wie: \n \t \" (mehr wird eigentlich nicht gebraucht, meine ich)


Was meinst du mit "mehr wird nicht gebraucht"? Woher weißt du das? (Weiß ich wieder einmal etwas nicht, was ich wissen sollte?)



jansen hat gesagt.:


> 6. nein, die datenmengen passen allemal in den QRCode, die spezielle anwendung erfordert nur weniger
> dazu: der qrcode wird ja an einer stelle eingelesen , d.h. aufgenommen und decodiert
> performanter weise sollte der code nicht unnötig groß sein, deswegen die beschränkung auf "50 zeichen" anstelle von "115 zeichen"
> 
> ...


Wie bereits gesagt wurde: Die Informationsdichte ist begrenzt. Man kann nicht einfach alles auf die Hälfte schrumpfen lassen.



jansen hat gesagt.:


> 9.base64 haben wir doch schon ausgeschlossen!
> ich weiß jetzt auch nicht warum du (ich dutze dich jetzt einfach mal) aufeinmal den string wieder größer machen willst
> - möchtest du mich ärgern^^
> nochmal mein Hauptziel:
> mache GROß-String zu kleinString


Ich will dich nicht ärgern, falls du das wissen wolltest. Es ist nur einfach so, dass du einen Verlust in der Informationsdichte hinnehmen musst, wenn du nicht alle möglichen Bitkombinationen zulassen kannst (sprich, wenn dein Zeichenvorrat für Zeichen pro Byte kleiner ist als 256).

Ark


----------



## jansen (20. Mai 2010)

ich hab so das Gefühl, als wenn wir ständig aneinander vorbeireden.
Dabei meine ich es gar nicht so kompliziert, wie es wohl rüberkommt .

Das komplette Flussdiagramm kann ich nicht reinstellen, da dies kein opensource Projekt ist. 
Genaue Angaben kann ich nicht geben. 

Ich wollte lediglich nur wissen, ob es möglich wäre einen 115 Zeichen langen String zu einem ca. halb so großen String zu komprimieren, wobei die Elemente dieser beiden Strings aus ein und dem selben Zeichenvorrat sind.

pass auf jetzt, ganz logisch nochmal von Anfang erklärt:

Ausgangssituation:

ich habe einen strukturierten String (egal ob JSON,XML oder "Marke Eigenbau" das ist zunächst egal)
Nehmen wir jetzt einmal wir hätten einen strukturierten String "Marke Eigenbau", der wie Folgt aussieht:

"acercooperation...........;111111111,11;0123456789;80080080;eeeeeeeeeeeeegggggggggggaaaaaaaaaallll................"

das sind genau 115 Zeichen 
länger kann der String nicht werden (das ist so festgelegt!)

dann wird ein QRCode (dies ist ein spezieller 2D-Matrixcode, auf den ich hier nicht weiter eingehe)
aus diesem String erzeugt

je größer der String desto größer der QRCode
um den QRCode kleiner zu machen, muss auch ein kleinerer String encodiert werden

Das ist mein Ziel ich möchte einen kleineren QRCode, der die gleichen Daten beinhaltet wie der größere.
Der QRCodealgorithmus arbeitet nur mit Strings mit unseren schon oft genannten Zeichvorrat:

```
abcdefghijklmnopqrstuvwxyz $*%+-./:0123456789
```

Die Größe des QRCodes ist abhängig von der Art der Zeichen.
Es passen mehr Ziffern in einen QRCode als Kleinbuchstaben.
Es passen mehr Kleinbuchstaben als Großbuchstaben in einen QRCode.
Nochmal anders gesagt. Der QRCode mit "AA" als Inhalt ist größer als der QRCode mit "aa".
Deshalb wird der Anfangsstring nur in Kleinbuchstaben aufgenommen!
In diesem String fallen keine Steuerzeichen an! (wird jetzt so festgelegt).

Bis jetzt war von einer Komprimierung noch nicht die Rede.

Mein QRCode soll jetzt kleiner werden, ergo mache die DatenString kleiner ohne Informationen zu verlieren.

Geht soetwas denn überhaupt unter der Vorraussetzung, dass die komprimierte String den sleben Zeichvorrat von 
	
	
	
	





```
abcdefghijklmnopqrstuvwxyz $*%+-./:0123456789
```
 hat?

Denn dieser komprimierte String soll nun QREncoded werden.

VERSTEHN?


----------



## Ark (20. Mai 2010)

jansen hat gesagt.:


> Nehmen wir jetzt einmal wir hätten einen strukturierten String "Marke Eigenbau", der wie Folgt aussieht:
> 
> "acercooperation...........;111111111,11;0123456789;80080080;eeeeeeeeeeeeegggggggggggaaaaaaaaaallll................"
> 
> ...


Bis gerade eben dachte ich: "Jetzt wird's endlich klarer!", aber dann … das verstehe ich wieder nicht! Großbuchstaben erzeugen schneller größere QRCodes als Kleinbuchstaben. Aber hieß es nicht gerade die ganze Zeit, Großbuchstaben wären ausgeschlossen? Und um welche Länge geht es dir eigentlich: Um die Länge der Eingabe oder um die Länge der QRCodes?

Der String, den du da oben als Beispieleingabe zeigst, kann nicht aus dem Zeichenvorrat, den du darunter nennst, entstanden sein: Dem Zeichenvorrat fehlt ';'. Was stimmt denn nun? Ist das Beispiel eine gültige Eingabe oder stimmt der Zeichenvorrat?



jansen hat gesagt.:


> Mein QRCode soll jetzt kleiner werden, ergo mache die DatenString kleiner ohne Informationen zu verlieren.


Da gibt's bei mir wieder Fragezeichen! Was soll denn nun kleiner werden, die Eingabe für das QR-Ding oder die Ausgabe des QR-Dings?

Für mich stellt sich das gerade so dar:

Du möchtest (aus mir nicht nachvollziehbaren Gründen) einen String komprimieren. Dieser String entspringt dem oben genannten Zeichenvorrat. Nach der Kompression soll ein String rauskommen, der nur aus Zeichen desselben Zeichenvorrats besteht und die gleichen Informationen aufgenommen hat, aber dafür weniger Zeichen benötigt.

Dir ist dazu ferner bewusst, dass dann die ursprüngliche Kodierung des Strings futsch ist und die Komprimierung nicht immer glücken kann (es also mindestens eine Zeichenkette gibt, die 115 Zeichen lang ist und nicht komprimiert werden kann).



jansen hat gesagt.:


> Geht soetwas denn überhaupt unter der Vorraussetzung, dass die komprimierte String den sleben Zeichvorrat von
> 
> 
> 
> ...


Natürlich geht das. Das macht Deflate ja auch so: Dort ist die Eingabe jedes Byte [0x00 ; 0xFF] zugelassen, und rauskommen kann auch jedes Byte [0x00 ; 0xFF]. In deinem Fall ist es ähnlich, nur das halt nicht 256 Zeichen zur Verfügung stehen, sondern nur 45, weshalb ja nun die Anzahl der Symbole der Deflate-Ausgabe von 256 auf 45 reduziert werden muss. Dies geht aber nur, wenn dafür die Länge des Strings wieder zunimmt. Deswegen muss die Ausgabe von Deflate (die komprimierte Version also) jetzt länger werden, und zwar mindestens mit dem Faktor log(256) / log(45) = 1,4567.

Ark


----------



## jansen (21. Mai 2010)

hi erstmal danke ich antworte später
ich schau nochmal genauer rein
ich habe da glaub ich einen fehler gemacht 

bis später


----------



## jansen (21. Mai 2010)

hi danke!

kurzer hinweis zu den unklarheiten noch:
die Länge des Strings beeinflusst die Länge des QRCodes.
schraubt man an dem string so ändert man auch den qrcode (das habe ich aber schon geschrieben!)

wenn es mein ziel ist den qrcode zu reduzieren dann ist es mein unterziel auch den string zu reduzieren
(siehst du jetzt die relation zwischen STRING und QRCODE?)

aber jetzt weiß ich erstmal wo unser kommunikationsproblem steckt:
der oben genannte zeichenvorrat bezog sich auf den tatsächlichen Datenstring
der QRCode arbeitet mit dem US-ASCII (das war mein fehler)
demzufolge haben wir zum erfolgreichen QRcodieren die ASCII-Zeichen von 33 bis 127
-> tut mir leid das ist mir ebengrade aufgefallen -> meine schlampigkeit 



also neu :
________

-eingangsstring (US-ASCII ohne Steuerzeichen) zu komprimierten String (US-ASCII ohne Steuerzeichen)
-was tatsächlich in den eingangsString eingegeben wird ist eine Teilmenge von "US-ASCII ohne Steuerzeichen"
-tatsächlich stehen im eingangsstring zu beginn elemente der folgenden Menge drin: 
[a-z +$*-/,%]

zum thema großbuchstaben: großbuchstaben könnten in einen QRCode encodiert werden, dies tritt aber hier nicht auf (wir einigen uns darauf, dass nur kleinbuchstaben eingegeben werden- zumindest zu beginn- was dann im komprimierten string steht darf auch groß geschrieben sein)

also wenn ich das richtig verstanden habe:

ich müsste, wenn ich den deflate algo verwenden wollen würde, also nur die zeichen von
[0x21 bis 0x7F] zulassen (ascii 33 bis ascii 127)


----------



## jansen (21. Mai 2010)

IDEE:

erweiterter ASCII_____________.|_______________US-ASCII   (Zeichsatzbereich)
255_________________________|127___________________0   (ASCII-WERTE)

-> zu Beginn liegen alle Zeichen im US-ASCII-Bereich
-> nach der Komprimierung befinden sich negative werte im byte[] -> diese negativen Werte zu 255 "ergänzen" (also abziehen)

-> jetzt muss ich den QRCodecreator nur noch dazu bringen die erweiterten ASCII-Zeichen zu encoden 
und dann klappt das doch oder was meint ihr?


----------



## Ark (21. Mai 2010)

Na, bitte, so wird ein Schuh daraus. 

Wir haben also 95 Zeichen zur Verfügung, damit können wir locker Base64 verwenden. Cooler wäre natürlich, wenn wir Steuerzeichen auch verwenden könnten:


256 Zeichen --> Faktor 1 (beste Kompression, trivial)
128 Zeichen --> Faktor 1,142857~ (leicht zu berechnen)
95 Zeichen --> Faktor 1,217683... (schwer zu berechnen)
64 Zeichen (Base64) --> Faktor 1,3~ (leicht zu berechnen)
Meine Empfehlung: Base64 (wie schon des öfteren gesagt wurde): Ist standardisiert, leicht zu implementieren und sehr schnell und speicherschonend.

Bei 128 Zeichen muss die Länge extra gespeichert werden, wenn sie nicht ohnehin bekannt ist, weil es schwer wird, dort ein Padding durchzuführen. Ansonsten ist auch das leicht implementiert und sehr performant. 95 Zeichen haben zwar den Vorteil gegenüber Base64, eine minimal bessere Kompression zu ermöglichen, machen die Sache jedoch unverhältnismäßig kompliziert.

The choice is up to you. 

Ark

*EDIT:* Hm, jetzt kann also auf einmal das Ding doch (möglicherweise) mit 0x00 bis 0xFF (256 Zeichen) umgehen ...

Also, wenn es doch möglich ist, sei noch Folgendes gesagt:

Die Umrechnung von negativen Zweierkomplement-Zahlen in den bitgleichen positiven Bereich ist einfach [c]int wert = wertAlsByte & 0xFF;[/c].
Du solltest dir Gedanken um den Zeichensatz machen, eventuell spielt der nämlich eine Rolle. (Bei nur ASCII sollte es keine Probleme geben.)

Ark


----------



## jansen (21. Mai 2010)

aber wenn ich base64 verwende dann wird doch der string größer. oder nicht?

z.B. aus "hallo" wird "aGFsbG8="

das ist doch schlecht
oder wo meinst muss base 64 eingesetzt werden nach oder vor dem komprimieren?

Kompression soll ja den string kürzen!

EDIT:
VERDAMMT! Da ist ja ne lücke zwischen US-ASCII und erweiterter ASCII -
das Steuerzeichen "DEL" auf asciiwert "127" soll auch ignoriert werden - kann ja nicht als char in den string eingefügt werden und somit auch nicht encodiert werden


----------



## Ark (21. Mai 2010)

jansen hat gesagt.:


> aber wenn ich base64 verwende dann wird doch der string größer. oder nicht?
> 
> z.B. aus "hallo" wird "aGFsbG8="
> 
> das ist doch schlecht


Ja, es ist schlecht in Hinblick auf die Länge des Strings, aber notwendig, wenn du weniger als 256 Symbole zur Verfügung hast.

In 40 Bits, also 5 Bytes an Daten gehen allerhöchstens 40 Bits an Information rein. Ein Byte ist 8 Bit groß und bietet 2^8 = 256 Symbole. Diese 256 Symbole können aus dem Deflater rauskommen. Nun hast du aber nur noch (bspw.) 64 Symbole zur Auswahl, weil mehr Symbole nicht weiterverarbeitet werden können. Also muss man die Information, die in 8 Bit steht, irgendwie so umkodieren, dass es nur noch x*6 Bit werden, weil log(64)/log(2) = 6 ist, die 64 Symbole also 6 Bit zur Kodierung brauchen. Und dann kommt man leicht darauf, dass x genau 4/3 = 1,333~ ist. Die neue Zeichenkette ist also 1,333mal so lang wie der komprimierte Datenstrom. Aus den ursprünglichen 40 Bit (5 Bytes) werden so 53,3 --> 54 Bit oder 6,75 --> 7 Bytes, wobei von diesen 7 Bytes immer nur 3/4 benutzt werden, das letzte Viertel bleibt ungenutzt.

Oder wie denkst du dir, sollen die Informationen untergebracht werden? 


jansen hat gesagt.:


> oder wo meinst muss base 64 eingesetzt werden nach oder vor dem komprimieren?
> 
> Kompression soll ja den string kürzen!


Wie oben gesagt: Die Kompression kürzt ihn, erzeugt aber in der Ausgabe mehr Symbole, als weiterverarbeitet werden können. Deswegen muss die Anzahl der Symbole auf Kosten der Länge reduziert werden.



jansen hat gesagt.:


> EDIT:
> VERDAMMT! Da ist ja ne lücke zwischen US-ASCII und erweiterter ASCII -
> das Steuerzeichen "DEL" auf asciiwert "127" soll auch ignoriert werden - kann ja nicht als char in den string eingefügt werden und somit auch nicht encodiert werden


Hm, entweder es liegt daran, dass ich wirklich keine Ahnung habe, oder es liegt an der Weiterverarbeitung. Jedenfalls höre ich hier gerade zum ersten Mal, dass man 0x7F nicht in einem char und nicht in einem String speichern könnte.

*EDIT:* Du solltest dir vllt die anderen Konstruktoren von Deflater und Inflater angucken und [c]nowrap = true[/c] setzen, vielleicht spart das noch etwas Speicher (wenn ich die Dokumentation jetzt richtig verstanden habe).

Ark


----------



## jansen (21. Mai 2010)

mein problem sind jetzt die steuerzeichen!
wie kann man in einem string signalisieren, dass dort an einer bestimmten stelle ein steuerzeichen auftritt- und zwar möglichst mit EINEM zeichen

mit zwei charaktern wär es ja kein problem: 
z.B. ASCII =28	HEX=0x1C	das entspräche FS mit einen möglichen Ausdruck: ^\

@ark 
ich schau mir mal die Konstruktoren bzgl "nowrap" genauer an auf jeden fall danke für den tipp
Base64 werde ich denk ich nicht verwenden, da mein oberstes ziel dann zerstört werden würde

EDIT:
DANKE für den Tipp mit dem "nowrap"-wert
dadurch hab ich eine verkürzung des strings von 115 auf 57 das sind 6 zeichen weniger!!!

wenn wir jetzt noch das problem mit den steuerzeichen eleminieren könnten wäre das schon ein fortschritt


----------



## Ark (21. Mai 2010)

Eine kurze Frage: Bist du dir wirklich sicher, das mit den Steuerzeichen wirklich verstanden zu haben? Wie lang ist denn folgender String s:

```
String s = "Seine Antwort war \"Nein!\", aber\ndas störte nicht.";
```
Ark


----------



## jansen (21. Mai 2010)

ja das sind C- steuerzeichen
ich hatte aber die steuerzeichen aus der ascii tabelle gemeint
wie zum Bleistift: DEL, NUL, ACK,BEL, ...

Steuerzeichen ? Wikipedia

einige von denen haben keine "C"-darstellung

trotzdem kommen Sie als werte in der ASCII-Tab vor und somit auch zwangsläufig im komprimierten string

und diese werte habe ich gemeint,
dass man ein Newline problemlos mit \n darstellen kann ist mir klar

und zwar habe ich die Steuerzeichen gemeint, die erst beim komprimieren entstehen!


----------



## Ark (21. Mai 2010)

jansen hat gesagt.:


> ja das sind C- steuerzeichen
> ich hatte aber die steuerzeichen aus der ascii tabelle gemeint
> wie zum Bleistift: DEL, NUL, ACK,BEL, ...


Ja, aber die sind doch auch alle nur 1 Zeichen bzw. (über ASCII) nur 1 Byte groß. ???:L Oder muss um den String noch eine Art Hülle, weil dieser z.B. in einem Quelltext noch verwendet wird und dieser Quelltext nicht größer als eine bestimmte Anzahl von Zeichen sein darf?

Hm...

Also ich verstehe es immer noch nicht ganz, aber wenn ich einen Rat geben darf: Komprimiere den String wie gehabt und wende anschließend Base64 auf die komprimierte Version an. Warum willst du denn den String so fanatisch verkleinern, obwohl es vielleicht gar nicht nötig und prinzipiell sowieso nicht immer möglich ist?

Ark


----------



## jansen (21. Mai 2010)

es ist nötig den string zu verkleinern ansonsten bräuchte ich den ganzen kompressionskram nicht!

und nochmal zu den steuerzeichen:
soh hat z.b kein c-äquivalent
hab mir aber schon was einfallen lassen!

schreibs dann nachher hier rein 
bis denne


----------



## Ark (21. Mai 2010)

jansen hat gesagt.:


> und nochmal zu den steuerzeichen:
> soh hat z.b kein c-äquivalent


Öhm, doch, nennt sich in C [c]\x01[/c] bzw. [c]\u0001[/c] oder schlicht [c]1[/c]:

```
char soh; // und jetzt dreimal die gleiche Zuweisung:
soh = 1;
soh = '\u0001';
soh = '\x01'; // nur in C
```



jansen hat gesagt.:


> hab mir aber schon was einfallen lassen!
> 
> schreibs dann nachher hier rein


Ah, das klingt gut. Na ja, ich bin gespannt. 

Ark


----------



## jansen (21. Mai 2010)

so da bin ich wieder
also:
du hast schon recht, dass man SOH als \u0001, \x01 und 1 ausdrücken kann

aber man erkennt dies nicht im string: 
BSP:

```
String einkomprimierterString = new String("\x01 ist ein Steuerzeichen, ebenso wie \x02");
//Ausgabe des Strings würde folgendes ergeben:
[] ist ein Steuerzeichen, ebenso wie []
//[] ist dieses komische Quadrat, welches immer dann auftaucht, wenn ein Zeichen nicht dargestellt werden kann
```

man kann hinterher nicht mehr feststellen, welcher byte[]-Code hinter den "[]" steckt, da die Auswertung später über den reinen String passiert (ich hoffe das ist einiger Maßen verständlich, wenn nicht dann sofort meckern )

Meine Überlegung: 

nach dem im komprimierten byte[] nur positive Zahlen(ist mir schon geglückt) von 0 bis 255 drinne stehen, werden die elemente des byte[] herausgesucht, die als steuerzeich interprtiert werden

d.h:

bsp: byte[] kompriBytes : 65 65 1 66                     //diese werte stehen im byte
in einen String gepackt müsste es das hier ergeben:
"AA[]B"

[] wäre aber eigentlich SOH

also, sage ich: 
an stelle aller steuerzeichen, die im string auftreten, packe ich eine kombination aus 2 verfügbaren zeichen rein

darausfolgt: 

NUL entspricht ^!
SON enspricht ^#
.
.
.
DEL entspricht ^B
^ entspricht dann ^^

so sind zwar statt einem zeichen zwei enthalten, aber den obulus gehe ich ein

also sähe der String aus dem beispiel wie folgt aus:

"AA^#B"

beim empfänger weiß ich dann:

byte[] komprimierteb={byte(A),byte(A),byte(SOH),byte(B)} 

was hältst du davon?
Habe ich eventuell etwas übersehen?


----------



## Ark (21. Mai 2010)

jansen hat gesagt.:


> aber man erkennt dies nicht im string:
> BSP:
> 
> ```
> ...


Es klingt seltsam, sehr seltsam. 

Erfolgt die Auswertung von Menschen, die die Glyphen entziffern müssen? Ich denke nämlich nicht! Nur weil die Zeichen nicht vernünftig angezeigt werden, heißt das nicht, dass sie nicht korrekt gespeichert wären.

Mal zur Verdeutlichung:

```
// eine Maschine erzeugt einen String mit allen ASCII-Zeichen:
StringBuilder sb=new StringBuilder(128);
for(int i=0;i<128;i++){
	sb.append((char)i);
}
String alleASCII = sb.toString();
```
Wenn du dir das ausgeben lässt, sieht es vielleicht nach Müll aus, aber es ist nach wie vor alles korrekt gespeichert:

```
// alleASCII ist der String von eben
for(int i=0;i<alleASCII.length();i++){
	System.out.println((int)alleASCII.charAt(i));
}
```
Wie du vielleicht siehst: Innerhalb von Java sind Steuerzeichen in Strings kein Problem. (Mit anderen Unicode-Zeichen geht es genauso.) Warum also willst du Escape-Sequenzen drumherum bauen? Diese Escape-Sequenzen sind doch nur dazu da, um in einem _Quelltext_ wie einem Java-Quelltext diese Zeichen eingeben zu können, ohne dass der Compiler auf Probleme stößt oder meckert. Im laufenden Programm ist es vollkommen egal, wie die Zeichen da reingekommen sind: ein SOH ist ein SOH, und wie es kodiert wird, steht auf einem völlig anderen Blatt (sprich: ist dann nicht mehr relevant).



jansen hat gesagt.:


> [] wäre aber eigentlich SOH


Es wäre eines und _es ist auch eines!_ Es sieht zwar doof auf dem Bildschirm aus, aber intern ist SOH gespeichert.



jansen hat gesagt.:


> was hältst du davon?
> Habe ich eventuell etwas übersehen?


Ja: Der Aufwand ist schlicht nicht nötig, es sei denn, dieser QR-Code hat wirklich Probleme mit Steuerzeichen.

Bist du dir immer noch sicher, dass Steuerzeichen wirklich ein Problem sind? Hast du schon einmal eine Verarbeitung von Anfang bis Ende vorgenommen, ohne dich von seltsam anmutenden Bildschirmausgaben verwirren zu lassen?

Ark


----------



## jansen (21. Mai 2010)

kurze antwort: ja , ich habe schon einmal einen string QRcodieren lassen, in dem nichts lesbares steht.
der algorithmus konnte damit nicht umgehen, da er sich die zeichen aus dem string nimmt und nicht etwa die bytes. 

du weißt doch auch gar nicht wie der algo funktioniert- deswegen sehe ich auch deine argumentation nicht ein.

am ende hast du eh immer was zu meckern 
wenn das jetzt hier klappt dann bin ich zu frieden

egal wie man zum ziel kommt, es gibt ja viele wege
der eleganteste ist mein weg nicht das gebe ich zu 
vielleicht zu kompliziert- das gebe ich auch zu 

aber mehr zeit um über diese sache nachzudenken habe ich nicht, obwohl ich das gerne würde!

auf jeden fall danke ich dir für deine denkanstöße, ark!
ohne deine hinterfragungen wäre ich wahrscheinlich nicht zu diesem resultat gekommen

zu deiner aussage: soh ist ein soh, und wie es kodiert wird, steht auf einem völlig anderen Blatt
das ist richtig
ich möchte nur nicht das in dem string steuerzeichen stehen - is einfach ne schlichte vorgabe vom arbeitgeber  

bis denne antenne

ich werde denk ich mal noch ne abschlussbemerkung schreiben wenn das hier alles gelaufen ist

tschuss


----------

