001 package de.hska.java.aufgaben.ausdruecke;
002
003 /**
004 * Enthält eine main-Methode, die ein char-Wert (16 Bit Unicode)
005 * in den entsprechenden UTF-8 int-Wert konvertiert.
006 * <p>
007 * Hier geht es zur <a title="Zum Aufgabentext dieser Java-Übungsaufgabe"
008 * href="http://www.home.hs-karlsruhe.de/~pach0003/informatik_1/aufgaben/datentypen.html#unicode_nach_utf8">Beschreibung dieser Java-Aufgabe</a>
009 * </p>
010 *
011 * @author Christian Pape
012 */
013 public class UnicodeNachUTF8 {
014
015 /**
016 * Konvertiert ein char nach UTF-8 mit Hilfe eines einzigen
017 * Ausdrucks. Man beachte, dass dieser nicht wirklich lesbar ist.
018 * Insbesondere die Kommentare sind notwendig, damit ersichtlich
019 * wird, was der Ausdruck überhaupt macht.
020 * In der Praxis sollten besser die drei Fälle mit if-else abgefragt werden,
021 * damit der sequentieller Berechnungsablauf erkennbar ist.
022 * Ebenso könnten Teilergebnisse in Variablen zwischengespeichert werden.
023 */
024 public static void main(String[] args) {
025 char c = 'ä';
026 int utf8 = 0;
027
028 System.out.println(Integer.toBinaryString(c));
029
030 utf8 = ( 0 == (c & 0xFF80) // höchstens ersten 7 Bits gesetzt
031 ? c // c ist selbst der Unicode
032 : ( 0 == (c & 0xF800 ) // ersten 11 Bits gesetzt
033 ? ( // Bits für das 1. Byte bestimmen
034 (((c >> 6) & 0x001F) << 8
035 | 0xC000) ) // führende binäre 110
036 // 2. Byte hat ersten 6 Bits ohne die anderen
037 | (c & 0x003F)
038 | 0x0080 // führende binäre 10
039 : ( // 16 Bits gesetzt
040 // 1. Byte
041 (c >> 12 & 0x0F | 0xE0) << 16
042 | // 2. und 3. analog wie oben
043 (((c >> 6) & 0x003F) << 8 | 0x8000) )
044 | (c & 0x003F) | 0x0080
045 ) ) ;
046
047 System.out.println(Integer.toBinaryString(utf8));
048
049 // Besser so (nicht getestet)
050 if ( 0 == (c & 0xFF80) ) { // c hat höchstens 7 Bits
051 utf8 = c;
052 } else if ( 0 == (c & 0xF800 ) ) { // c hat höchstens 11 Bits
053 utf8 = (((c >> 6) & 0x001F) << 8
054 | 0xC000 ) // vorderen 5 Bits mit führendem binären 110
055 |(c & 0x003F)
056 | 0x0080; // hinteren 6 Bits mit führendem binären 10
057 } else { // mindestens 12 Bits sind gesetzt
058 utf8 = (c >> 12 & 0x0F | 0xE0) << 12 // 1. Byte
059 // 2. und 3. Byte analog wie oben
060 | (((c >> 6) & 0x003F) << 8 | 0x8000)
061 | (c & 0x003F)
062 | 0x0080;
063 }
064
065 // Oder auch so (auch nicht getestet)
066 int byte1 = 0,
067 byte2 = 0,
068 byte3 = 0;
069
070 if ( 0 == (c & 0xFF80) ) { // c hat höchstens 7 Bits
071 byte3 = c;
072 } else if ( 0 == (c & 0xF800 ) ) { // c hat höchstens 11 Bits
073 byte2 = ((c >> 6) & 0x001F) | 0xC0;
074 byte3 = (c & 0x003F) | 0x0080; // hinteren 6 Bits mit führendem binären 10
075
076 } else { // mindestens 12 Bits sind gesetzt
077 byte1 = (c >> 12 & 0x0F | 0xE0);
078 byte2 = (((c >> 6) & 0x003F) | 0x80);
079 byte3 = (c & 0x3F)| 0x80;
080 }
081 utf8 = (byte1 << 16) | (byte2 << 8) | byte3;
082 }
083
084 }