===== Kodierung von Buchstaben und Symbolen ===== ==== ASCII ==== * 7 Bit, keine Akzente, kaum Sonderzeichen. https://en.wikipedia.org/wiki/ASCII ==== Latin1 aka. ISO-8859-1 und Windows-1252 ==== * 8 Bit, deckt viele Sonderzeichen Westeuropas ab. Windows-1252 (auch CP-1252) ist eine Erweiterung von Latin1 und nutzt dort undefinierte Zeichen (z.B. das € Zeichen). In unserer Region nach UTF8 wohl die verbreitetste Kodierung. https://en.wikipedia.org/wiki/Windows-1252 ==== Unicode ==== Idee: Jedem Symbol seine eigene Nummer. Plus Möglichkeiten zum Setzen von Akzenten, Festlegen und Ändern der Schreibrichtung etc. Zum Kodieren dieser Nummern gibt es verschiedene Systeme. Das am weitesten verbreitete System ist UTF-8. **Klarstellung** Unicode ist noch Kodierung in Bits und Bytes, sondern nur eine Nummerierung der Symbole (bzw. Kodierung als natürliche Zahl). Wie dann diese Zahl effektiv mit Bits und Bytes kodiert wird, dafür gibt mehrere gebräuchliche Varianten. https://en.wikipedia.org/wiki/Unicode === UTF-8 === UTF-8 ist die am häufigsten verwendete Kodierung (im Sinne von "Umsetzung in Bits und Bytes") für Unicode. Es ist ein faszinierend durchdachtes Format. Siehe z.B. https://en.wikipedia.org/wiki/UTF-8#Advantages_and_disadvantages ==== Kodierung und Dekodierung von Unicode nach und von UTF-8 ==== Referenz: https://en.wikipedia.org/wiki/UTF-8#Description # Die untersten 6 Bit mit # höchstem Bit gesetzt als string def folgebyte(byte) ((byte & 0b11_1111) | 0b1000_0000).chr end # Eingabe: Zahl (Unicode des Symbols) # Ausgabe: String mit diesem Zeichen def to_utf8(unicode) utf8="" # Leerer String # String aufbauen if (unicode<0x80) # pure ASCII utf8 = unicode.chr elsif unicode<0x800 byte1 = ((unicode >> 6) & 0b1_1111) | 0b1100_0000 utf8 = byte1.chr + folgebyte(unicode) elsif unicode < 0x10000 byte1 = ((unicode >> 12) & 0b1_1111) | 0b1110_0000 utf8 = byte1.chr + folgebyte(unicode >> 6) + folgebyte(unicode) else byte1 = ((unicode >> 18) & 0b1_1111) | 0b1111_0000 utf8 = byte1.chr + folgebyte(unicode >> 12) + folgebyte(unicode >> 6) + folgebyte(unicode) end # Dem String sagen er sei UTF-8 kodiert (sonst ASCII-8Bit) utf8.force_encoding(Encoding::UTF_8) end # Eingabe: String mit einem Unicode-Zeichen # Ausgabe: Zahl (entsprechende Unicode-Nummer) def to_unicode(utf8) b = utf8.bytes # Ein Array mit entsprechenden Bytes # Resultat der Funktion: Resultat des letzten Ausdrucks. # In diesem Fall das Resultat des case-statements. # Resultat von case: # Letztes Resultat des entsprechenden # when. case b.size # Anzahl Einträge when 1 b[0] when 2 (b[1] & 0b11_1111) | ((b[0] & 0b1_1111) << 6) when 3 (b[2] & 0b11_1111) | ((b[1] & 0b11_1111) << 6) | ((b[0] & 0b1111) << 12) when 4 (b[3] & 0b11_1111) | ((b[2] & 0b11_1111) << 6) | ((b[1] & 0b11_1111) << 12) | ((b[0] & 0b111) << 18) end end # Einige Tests: "Aö♣♥✓✌计算机科学𝅘𝅥𝅮".each_char{|c| puts "Code von #{c} ist #{to_unicode(c)} sollte sein: #{c.ord} = 0x#{c.ord.to_s(16)}" } [0x261E, 0x2744, 0x1D120, 0x1D160, 0x24, 0xA5, 0x20AC].each{|u| puts "Unicode 0x#{u.to_s(16)}=#{u} : #{to_utf8(u)} und zurück: #{to_unicode(to_utf8(u))}" } ===== WTF? ===== Der folgende Ruby-Code gibt 42 aus (wenn man diesen kopiert und nicht abschreibt) o = -1 о = 7 ο = о+o puts (ο-o)*ο