Zeichensatz-Umwandlungen

Kennst sich irgendjemand mit Umwandlungen von einer Unicode-Zahl zum Unicode-Character und umgekehrt aus?

Bisher habe ich dieses hier:

	public static int ascA(String string1) {
		return (int)string1.charAt(0);
	}
	public static int ascB(String string1) {
		return (int)string1.charAt(0);
	}
	public static int ascW(String string1) {
		java.nio.ByteBuffer bb = java.nio.charset.Charset.forName("UTF-16").encode(java.nio.CharBuffer.wrap(string1));
		return bb.getInt();
	}
	public static int asc(String string1) {
		java.nio.ByteBuffer bb = java.nio.charset.Charset.forName("UTF-8").encode(java.nio.CharBuffer.wrap(string1));
		
		byte[] b = bb.array();
		System.out.println("---------");
		for (int i=0; i<=b.length-1; i++) {
		  System.out.println((int) b**);
		}
		System.out.println("---------");
		return bb.getInt();
	}
	public static String chrA(int zeichen) {
		byte[] b = { (byte)zeichen };
		try {
			return (new String(b, "US-ASCII"));
		} catch (Exception e) {
			return (new String(b));
		}
	}
	public static String chrB(int zeichen) {
		byte[] b = { (byte)zeichen };
		try {
			return (new String(b, "ISO-8859-1"));
		} catch (Exception e) {
			return (new String(b));
		}
	}
	public static String chrW(int zeichen) {
	        java.nio.ByteBuffer bTemp = java.nio.ByteBuffer.allocate(4);
	        bTemp.putInt(zeichen);
		byte[] b = bTemp.array();;
		try {
			return (new String(b, "UTF-16"));
		} catch (Exception e) {
			return (new String(b));
		}
	}
	public static String chr(int zeichen) {
	        java.nio.ByteBuffer bTemp = java.nio.ByteBuffer.allocate(4);
	        bTemp.putInt(zeichen);
		byte[] b = bTemp.array();
		try {
			return (new String(b, "UTF-8"));
		} catch (Exception e) {
			return (new String(b));
		}
	}
}```

Also bei chr() will ich einen UTF-8-Wert eingeben und ein UTF-8-Character erhalten.
Bei chrW() will ich einen UTF-16-Wert eingeben und ein UTF-16-Character erhalten.
Bei chrA() will ich einen ASCII-Wert eingeben und ein ASCII-Character erhalten.
Bei chrB() will ich einen Binary-Wert eingeben und ein Binary-Character erhalten.

Bei asc() will ich ein UTF-8-Character eingeben und einen UTF-8-Wert erhalten.
Bei ascW() will ich ein UTF-16-Character eingeben und einen UTF-16-Wert erhalten.
Bei ascA() will ich ein ASCII-Character eingeben und einen ASCII-Wert erhalten.
Bei ascB() will ich ein Character eingeben und einen Binary-Wert erhalten.

Insbesondere sollte gelten, bei einem x, das Integer ist und einen beliebigen Wert zugewiesen bekommen hatte:
asc(chr(x)) == x
ascW(chrW(x)) == x
ascA(chrA(x)) == x
ascB(chrB(x)) == x
Vor allem halt bei den Unicode-Umwandlungen sollte es zutreffen.

Nun habe ich entsprechendes mit dem Thai-Zeiechensatz versucht zu testen:
```import javax.swing.*;

public class MyThai {

  public static void main(String[] args) {
    String s = "Hier steht ein Text";
    s += Strings.chr(64);
    s += Strings.chr(60);
    s += "สวัสดี";
    s += Strings.chr(13) + Strings.chr(10);
    s += "new Line";
    s += Strings.chr(0xe0b889);
    s += Strings.chr(0xe0);
    s += Strings.chr(0xb8);
    s += Strings.chr(0x89);
    s += Strings.chr(0x89b8e0);
    s += Strings.chr(0xe0b893);
    s += Strings.chr(64)+Strings.chrB(60);
    s += Strings.chr(13) + Strings.chr(10);
    s += Strings.chr(0x3623)+Strings.chr(0x3633)+Strings.chr(0x3609)+Strings.chr(0x3609)+Strings.chr(0x3637)+Strings.chr(0x3657);
    s += Strings.chrW(13) + Strings.chrW(10);
    s += Strings.chrW(0x3623)+Strings.chrW(0x3633)+Strings.chrW(0x3609)+Strings.chrW(0x3609)+Strings.chrW(0x3637)+Strings.chrW(0x3657);
    s += Strings.chrW(13) + Strings.chrW(10);
    s += Strings.chrW(0x0e07)+Strings.chrW(0x0e0c)+Strings.chrW(0x0e0f);
    s += Strings.chrW(13) + Strings.chrW(10);
    s += Strings.chrW( 3626 ) + Strings.chrW( 3623 ) + Strings.chrW( 3633 ) + Strings.chrW( 3626 ) + Strings.chrW( 3604 ) + Strings.chrW( 3637 );
      
    JOptionPane.showMessageDialog(null, s);
    
    System.out.println(Strings.ascB("A"));
    System.out.println(Strings.ascW(Strings.chrW(47)));
    System.out.println(Strings.asc(Strings.chr(47)));
    System.out.println(Strings.asc(Strings.chr(0x89b8e0)));
    System.out.println(Strings.asc(Strings.chr(0x89b8e1)));
  }

}```

Und irgendwie funktioniert es nicht so ganz.
Stehen die Thai-Zeichen in einem String ( s += "สวัสดี"; ), dann funktioniert es wunderbar. Sowohl unter Linux als auch Windows.
Bei einem » s += Strings.Chr(0xe0b889); « erscheint das Zeichen bei Linux ganz normal. Bei Windows steht dem jedoch noch ein weiteres Zeichen davor. Bei den anderen Characters genauso.
Und ein »  System.out.println(Strings.Asc(Strings.Chr(0x89b8e0))); « liefert dummerweise die gleiche Ausgabe wie ein » System.out.println(Strings.Asc(Strings.Chr(0x89b8e1))); «. Und beide Zahlen liegen völlig neben der Zahl, die sie sein sollten.

Kennt sich hier somit irgendjemand mit Zeichensatz-Umwandlungen aus?

Grüße
theuserbl

kannst du das in Beispielen näher erläutern, was genau soll der erzeugte String enthalten?
kodiert einen bestimmten Inhalt? ne, „ein UTF-8-Character erhalten“…

wenn den Char an sich direkt, dann gibt es für Java-Strings + Datentyp char nur EINE Art von Chars, nämlich Unicode,
der kann nicht kodiert sein,
Kodierungen betreffen byte-Darstellungen davon

und was soll 0x89b8e1 sein? ein einzelner Char? was heißt ‚das Zeichen‘, welches Zeichen mag das sein?
soweit aktuell (mal wieder) halb informiert, geht Unicode maximal bis Character.MAX_CODE_POINT = 0x10ffff,
da liegt dein Wert drüber,

sollte es eine UTF16-Darstellung von 4 Bytes sein? liegt nicht ganz fern bei deiner Methoden-Auswahl,
aber dafür wären dann volle 8 Hexa-Zeichen benötigt, nicht nur 6…

ich habe selber ein wenig in zwei Richtungen gebastelt, bis irgendwas hinkam,
muss nicht unbedingt dein Ziel sein,
ob für sich allgemein richtig durchaus auch mit dicken Zweifeln :wink: :

        // Unicode-Codepoint zu UTF8-byte[] und zurück
        {
            int k = 0x10fffe;
            System.out.println("k1: " + k);
            char[] c = Character.toChars(k); // werden zwei Chars, besonderer Codepoint über char-Wertebereich
            String st = new String(c); // String-Länge 2, sichtbare Ausgabe ein Zeichen
            byte[] bUTF8 = st.getBytes("UTF-8");
            System.out.println(Arrays.toString(bUTF8));

            String st2 = new String(bUTF8, "UTF-8");
            char[] c2 = st2.toCharArray();
            int k2 = Character.codePointAt(c2, 0);
            System.out.println("k2: " + k2); // == k
        }

        // UTF16 zu Unicode-String und zurück
        {
            int k = 0xD834DD1E;
            System.out.println("k1: " + k);
            String st = Strings.chrW(k); // enthält auch so einen speziellen Codepoint, String-Länge 2, sichtbare Ausgabe ein Zeichen

            ByteBuffer bb = Charset.forName("UTF-16BE").encode(CharBuffer.wrap(st));
            int k2 = bb.getInt();
            System.out.println("k2: " + k2); // == k
        }

der UFT16-Wert ist aus dem Wiki-Artikel UTF-16 – Wikipedia

während chrW()-Methode (bisher) ausreichend ist,
muss auf Rückweg „UTF-16BE“ als Charset verwendet werden, sonst kommt es bei mir nicht hin…


edit: bei einem kürzeren UFT16-Wert, €-Zeichen 0x20AC etwa, wird immer noch ein String mit zwei Zeichen erzeugt, char 0 vor dem Euro-char,

zur finalen Berechnung von k2 funktioniert das noch in diesem direkten Beispiel, führende 0-Bytes stören die Rechnung nicht,
insgesamt aber wohl nicht gut, falls mehrere umgewandelte Strings zusammgefasst werden,

da muss geschickt wieder auftrennen dass die richtigen Chars zusammenkommen…,
für Codepoint eh eine besondere Aufgabe

charW mit allocate(2) und putChar() usw. würde einen kleineren String „€“ erzeugen,
Rückumwandlung auch mit getChar() vom ByteBuffer…, ganz schön Aufwand, muss doch besser gehen

Thx @ SlaterB. Das ist genau das, was ich wollte.

Grüße
theuserbl