# Char Array mit Sonderzeichen in String umwandeln



## Mondmann1 (19. Dez 2005)

Hallo.
Ich bin noch ganz "frisch" in der Java Progrmamierung und habe gleich mal ne Frage:
Ich möchte aus einer C/C++ Applikation eine Java Anwendung machen.
In der bisherigen Applikation ist eine Unternehmenseigene Verschlüsselungsfunktion die Sonderzeichen erzeugt.
Es sind weitgehend Anmeldedaten, die verschlüsselt werden und als Text zum Server geschickt werden. Dieser entschlüsselt das Ganze und schickt die Antwort wieder an den Client - der wiederrum entschlüsselt diese.


Innerhalb der Funktion wird aus einem leserlichen Text ein unleserlicher gemacht.
Erst mache ich ein Char-Arry, welches ich mit Zeichen fülle:

Das sieht dann so aus:
arr[0]=252;
arr[1]=165;
arr[2]=164;..usw

Diese Zeichen brauche ich als Verschlüsselung für eine Socket Server/Client- Komunikation.
Da die Funktion einen String zurückgibt, möchte ich diese Zeichen in einen String umwandeln.

Mittels:


```
try
{
  PrintWriter out = new PrintWriter(
  new OutputStreamWriter(System.out, "Cp850") );

  out.println( arr );
  out.flush();
}
catch ( UnsupportedEncodingException e ) {
  System.err.println(e);
}
```

Wandle ich das Array um, so daß ich die entsprechenden Zeichen bekomme, welche auch korrekt sind:

arr[0]='ü'
arr[1]='¥';
arr[2]='¤';...usw.

Jetzt habe ich ja nur einen Output Stream, ich brauche das Ganze aber als String.

Wenn ich jetzt aber das Char-Array in einen String umwandle, dann macht er daraus wieder ganz andere Zeichen

String str = new String(s_array);
System.out.println(str);

In str stehen jetzt völlig andere Zeichen mit denen ich nichts anfangen kann.

Warum ist das so und wie kann ich das Char Array in einen String umwandeln, damit er die o.g. Zeichen beibehält?

Das Ganze geschieht zur Laufzeit und ist natürlich jedesmal anders.
Es soll nirgends grafisch oder sonst wie dargestellt werden.

Danke schonmal Mondmann

Mondmann


_L-ectron-X hat die Code-Tags gesetzt._


----------



## Bleiglanz (19. Dez 2005)

new String(von einem Byte-Array) liefert dir einen String, der das Byte-Array im default-Encoding deiner Plattform dekodiert

du musst auch hier ein CharacterEncoding verwenden


----------



## SlaterB (19. Dez 2005)

hmm gehts jetzt um die Übertragung:

schreib doch in den String die Zahlen, die int-Werte,
z.B. "252-165-164", 

das dürfte sicherlich fehlerfrei übertragen werden 
und dann bestimmst du die einzelnen Zahlen und machst wieder chars draus

----------------

oder ist die Übertragung schon geschehen und du willst jetzt nur aus dem char-Array ein String machen?,
wieso genau funktioniert das jetzt nicht?
das char-Array enthält 252, 165, 164 und wenn du das in String wandelst kommen andere Zeichen raus?
welche anderen? wie soll das denn gehen dass da was anderes kommt als 252, 165, 164??

------------

oder gehts eher darum dass 'ü','¥' und '¤' in C++ einen anderen int-Wert haben aus in Java bzw. 
dass die int-Werte verschieden interpretiert werden so dass ein '¥' in C++ in Java was anderes ist?


also worum genau geht es eigentlich?, wer sendet zu wem?, möglichst mit einem Zeichen als Beispiel


----------



## Mondmann1 (19. Dez 2005)

Ok also folgendes:
Vom Prinzip her ist so.
Ich lese anmeldedaten von einer Maske ein.
Diese lauten zB. Mustervorname,Musternachname.
Diese Packe ich ein einen String zusammen mit einer Loginanforderung:
"LOGIN\nMustervorname,Musternachname" lautet dann der Gesamte String.

Dieses muss ich jetzt verschlüsseln und dann zum Server schicken.
Dieser entschlüsselt das Ganze wieder, verarbeitet es und schickt eine verschküsselte Antwort zurück.
Nach dessen Entschlüsselung lautet es Sinngemäß:

"Willkommen User Musternachname".

So.
Nun folgendes.
Bevor ich das über den Socket zum Server schicke, jage ich den eingelesenen Text durch die Verschlüsselungsfunktion.
Rückgabewert ist ein verschlüsselter String.

Die Funktion ist folgendermaßen aufgebaut:


```
class crypt
{

	
	int i=0,j=0,x=0,z=0,len=0;
		String crypt1 (String ptr,int krypt) // Methode Setzen
    	{ 
    	
    	len=ptr.length();
    	char[] s_array=new char[len];   
    	
    	
    		for(i=0,x=0; i<len; i++,x++)
  			if((j = ptr.charAt(x)) != 0 && j != 0xff)
   				
   				if(krypt==1)
   				{
   			
				s_array[x]=(char)//verschlüsselung...geheim
				s_array[x]+=256;
				
					
						
   				}
   						else
   					{
   						z=(char) //entschlüsselung geheim
                                               s_array[x]+=256;
   					}
    				
		


 try  (1)
    {
      PrintWriter out = new PrintWriter(
      new OutputStreamWriter(System.out, "Cp850") );

      out.println( s_array );
      out.flush();
    }
    catch ( UnsupportedEncodingException e ) {
      System.err.println(e); }

   
 (2)
 String str = new String(s_array);
     System.out.println(str);
	return str;
   		}
 }
```


Aufruf in Main:

```
String erg;
crypt c=new crypt();
erg=c.crypt1("LOGIN\nMustervorname,Musternachname,"1);

//erg zum Server senden...
```


So. An der Stelle wo jetzt s_array über den Outputstream ausgegeben wird werde die Zeichen korrekt angezeigt.(1)
Ich brauche das aber als Stream oder irgendwas was ich zum Server schicken kann, also mache ich aus dem Char Array einen String(2).
Hier werden die Zeichen jetzt anders als bei (1) angezeigt.
Ich brauche aber die Zeichen wie in (2).

Was ist jetzt der Unterschied zwischen (1) und (2)?
Ich schätze mal das liegt irgendwie an der Codierung der Zeichen, oder?
Aber wie kann ich aus dem Char Array einen korrekten String machen?
Oder ist die Vorgehensweise komplett falsch?

Ich hoffe so wirds etwas deutlicher...
grüße Mondmann1
[/code][/quote]


----------



## Bleiglanz (19. Dez 2005)

>>Was ist jetzt der Unterschied zwischen (1) und (2)?

(1) verwendet Cp850 um aus dem String bytes zu machen

>>Ich schätze mal das liegt irgendwie an der Codierung der Zeichen, oder?

ja

>>Aber wie kann ich aus dem Char Array einen korrekten String machen? 

einfach mit String.valueOf(meinCharArray)

beachte mal folgendes: ein CharArray ist so gut wie ein String, jedes Zeichen belegt 2Bytes usw. usf, von einem Encoding ist da noch gar nicht die Rede

s_array[x]+=256;

wenn du zu einem char ein int addierst, dann wird dabei erst mal nach int erweitert und dann (wegen des +=) gleich wieder zurückgecastet; dabei kann alles mögliche schiefgehen


----------



## Mondmann1 (19. Dez 2005)

Ich schätze mal es besteh ein grundsätzliches Verständnisproblem.

So wie unter (1) sind die Zeichen korrekt. So brauche ich sie in einem String den ich zum Server schicken kann.
Unter (2) kommt was anderes heraus mit dem der Server nichts anfangen kann, ich denke weil die Codierung zu Cp850 fehlt.

Die Frage ist also wie ich aus einem Char Array einen String mit Cp850 Codierung bekomme?
Oder?

Die +256 muss ich machen ,da aus der Verschlüsselung grundsätzlich negavite Zeichen herauskommen. Diese muss ich dann eben als Vorzeichenlos interpretieren, also +256.

 :bahnhof: 
Mondmann1


----------



## messi (19. Dez 2005)

Vielleicht solltest du während der Ver-/Entschlüsselung mit byte[] arbeiten, dann sparst du dir auch das +=256, und danach einen String mit String(bytes, "Cp850") erstellen.


----------



## Bleiglanz (19. Dez 2005)

> Die +256 muss ich machen ,da aus der Verschlüsselung grundsätzlich negavite Zeichen herauskommen.



ein char ist NIE negativ, das ist schon vorher verschwunden und dein ganzer Algorithmus möglicherweise im Eimer:

mach mal

```
char z = 0;
z -= 33; // macht erst ein int und castet sofort nach char zurück...
System.out.println((int)z);
```


----------



## Mondmann1 (19. Dez 2005)

messi hat gesagt.:
			
		

> Vielleicht solltest du während der Ver-/Entschlüsselung mit byte[] arbeiten, dann sparst du dir auch das +=256, und danach einen String mit String(bytes, "Cp850") erstellen.



Aber byte geht nur von -127 bis 128.
Ich habe aber Zeichen die bis 254 gehen.
Also kann ich mit Byte nicht daraus zugreifen.

So wie du es vorgeschlagen hast gehts leider nicht, es kommen definitiv die falschen Zeichen heraus.
Ich habs verglichen mit der C-Funktion, so wie ich unter (1) beschrieben hatte sinds exakt diesselben Zeichen, diese muss ich jetzt nur noch in einen String kriegen.

Ich kann ein Char.-Array nehmen, da ich as Ergebnis gleich in ein (char) Caste.
 Es kommen negative zahlen dabei heraus (-4,-252 usw) und wenn ic h+256 machen habe ich die positiven Äquivalente dazu.

Oje... das ist in C so einfach ...ich glaube ich muss mal nen JAva Kurs machen, es erscheint mir soch sehr kompliziert

Mondmann


----------



## messi (19. Dez 2005)

Mondmann1 hat gesagt.:
			
		

> messi hat gesagt.:
> 
> 
> 
> ...


Spielt kein Rolle, wenn du später für die Zeichen eh char benutzt. Solange betrachtest du ein Byte als Folge von 8 Bits, egal wie das 8. Bit interpretiert wird.

Ich kenne zwar jetzt CP850 und euren super-uber-secret Algorithmus nicht, aber wenn es alles auf 8 Bit basiert und du byte nicht direkt zum Darstellen der Zeichen verwendest, sollte es kein Problem sein.


----------



## Mondmann1 (19. Dez 2005)

messi hat gesagt.:
			
		

> Mondmann1 hat gesagt.:
> 
> 
> 
> ...



Es ist kein super-uber-secret Algorithmus  es ist nur von der Firma emtwickelt und selbstverständlich nicht nach außen zu geben!
Es ist ja auch nicht so wichtig was da drin passiert es dreht sich nur um folgendes:

Ich  jetzt ein Int-Array welchen folgendes beinhaltet:

arr[0]=252;
arr[1]=165;
arr[2]=164;..usw 

Dieses sind nach ANSI Standard folgende Zeichen:

arr[0]='ü'
arr[1]='¥';
arr[2]='¤';...usw. 

Wie krieg ich das so in einen String?
Wie kann ich das entsprechend umwandeln?

Wenn ich zB.System.out.println(arr);
Kommt das heraus: "[I@"usw. also lauter Zeichen unter ANSI 128.


Mondmann


----------



## Bleiglanz (19. Dez 2005)

etwa so:

```
int[] arr=new int[3];
        arr[0]=252;
        arr[1]=165;
        arr[2]=164;
        
        byte[] arrByte = new byte[arr.length];
        for(int i=0;i<arr.length;i++){
            arrByte[i] = (byte)arr[i];
        }
        String s = new String(arrByte,"ISO-8859-1");
        System.out.println(s);
```


----------



## messi (19. Dez 2005)

Mondmann1 hat gesagt.:
			
		

> Es ist kein super-uber-secret Algorithmus  es ist nur von der Firma emtwickelt und selbstverständlich nicht nach außen zu geben!


Nun, die besten Algorithmen sind alle öffentlich. :wink: Aber du hast natürlich Recht.



			
				Mondmann1 hat gesagt.:
			
		

> Ich  jetzt ein Int-Array welchen folgendes beinhaltet:
> arr[0]=252;
> arr[1]=165;
> arr[2]=164;..usw


Warum nimmst du ein int[] und kein byte[]? Ob es jetzt 252 ist oder der 2er-Komplement-Wert, spielt wirklich keine Rolle, weil ja keine Daten verloren gehen.


			
				Mondmann1 hat gesagt.:
			
		

> Kommt das heraus: "[I@"usw. also lauter Zeichen unter ANSI 128.


hehe... das ist eine String-Representation einer Referenz: '[' steht für Array, 'I' steht für int und nach dem '@' kommt die Objekt-ID.


----------



## Mondmann1 (19. Dez 2005)

> hehe... das ist eine String-Representation einer Referenz: '[' steht für Array, 'I' steht für int und nach dem '@' kommt die Objekt-ID.



hmmm..und was genau heißt das jetzt?

Mondmann


----------



## messi (19. Dez 2005)

java.lang.Object.toString()

Du kannst nicht einfach 
	
	
	
	





```
int[] muh = new int[42];
System.out.println(muh);
```
 schreiben, weil es keine Standard-Darstellung für int[] gibt. Du musst schon selbst dafür sorgen, dass die einzelnen int im Feld korrekt interpretiert und ausgegeben werden.

Du hast meine Frage noch nicht beantwortet: Warum anfangs ein int[], wenn byte[] doch reicht?


----------



## Mondmann1 (19. Dez 2005)

Bleiglanz hat gesagt.:
			
		

> etwa so:
> 
> ```
> int[] arr=new int[3];
> ...



hmm..so gehts leider nicht es kommt dann folgender heraus:
"³Ññ" und was weiß ich noch alles...

Geht wohl so nicht...
Mondmann


----------



## SlaterB (19. Dez 2005)

es ist die Frage wieso bei 3 Zeichen "³Ñ>>" rauskommen kann..,
verwendest du genau den gleichen Code?

(edit: ah jetzt hast du ja auch nur 3 Zeichen)

den Umweg über byte kann man sich vielleicht sparen, bei mir liefert

```
char[] arr = new char[3];
		arr[0] = 252;
		arr[1] = 165;
		arr[2] = 164;
		String st = "";
		for (int i = 0; i < arr.length; i++) {
			st += arr[i];
		}
		System.out.println(st);
```
genau das was du anscheinend haben willst: ü¥¤

was kommt bei dir denn nun genau raus, wann willst du das verraten? 

hänge doch z.B. noch ein

```
for (int i = 0; i < st.length(); i++) {
			System.out.println("char "+i+": "+st.charAt(i)+" - "+((int) st.charAt(i)));
		}
```
dahinter, dann siehst du welche chars dadrin stehen,
vielleicht sieht man daraus leichter wo der Umwandlungsfehler liegt?
versuchs evtl. auch mal mit einer Schleife: alle chars von 1 bis 255 oder wie weit auch immer in ein char-Array,
dann in einen String und danach wieder die char-Werte ausgeben,
was kommt dann raus? auch wieder 1 bis 255 oder irgendwelche Sprünge?


----------



## Bleiglanz (19. Dez 2005)

gibst du das vielleicht einfach auf einer Windooof Konsole aus?

da wird nochmal alles verwurstet...


----------



## Mondmann1 (19. Dez 2005)

Bleiglanz hat gesagt.:
			
		

> gibst du das vielleicht einfach auf einer Windooof Konsole aus?
> 
> da wird nochmal alles verwurstet...



ja es ist eine Windoof Konsole.... :gaen:
Also es kommt das dabei heraus:

³Ñ┤¶Á§tÑõ»┤▄?ÈM?^

char 0: ³ - 252
char 1: Ñ - 165
char 2: ┤ - 180
char 3: ¶ - 244
char 4: Á - 181
char 5: § - 245
char 6: t - 116
char 7: Ñ - 165
char 8: õ - 228
char 9: » - 175
char 10: ┤ - 180
char 11: ▄ - 220
char 12: ? - 156
char 13: È - 212
char 14: M - 77
char 15: ? - 151
char 16: ^ - 94

Wobei ja zB- 252 eindeutig "ü" ist....

Oje...

 :autsch:  :autsch:


----------



## messi (19. Dez 2005)

Hier mal ein kleiner Gedankenanstoß:

```
int i = 252;
        byte b = (byte) i;
        char c = (char) (b & 0xff);

        System.out.println("i == " + i + " == 0x" + Integer.toHexString(i));
        System.out.println("b == " + b);
        System.out.println("c == " + (int) c + " '" + c + "'");

        byte[] ba = { (byte) 252, (byte) 165, (byte) 164 };
        String cp850 = new String(ba, "CP850");
        String iso88591 = new String(ba, "ISO-8859-1");
        System.out.println(cp850);
        System.out.println(iso88591);
```

'ü' ist im ISO-8859-1 bei 252 (0xFC) und im CP850 bei 129 (0x81).


----------



## Mondmann1 (19. Dez 2005)

Ich krieg einfach kein "ü" raus.


Also Ihr seid echt Super, Ihr helft mir hier so dolle,wofür ich euch dankbar bin, und ich peils halt überhaupt nicht. 
Am Besten ich mach die Kiste aus und vergrab mein Hirn tief uner der Erde.
Bis morgen
 :autsch:  ???:L 



Mondmann[schild=2 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]doof geboren und nix dazugelernt[/schild]


----------



## SlaterB (19. Dez 2005)

besteht denn überhaupt noch ein Problem?
anzeigen wolltest du die Strings doch sowieso nicht,

wenn die richtigen chars enthalten sind und nur bei Windows falsch angezeigt werden dann könnte die Kommunikation doch klappen?


----------

