Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

UTF-8 (Datentypen, Variablen und Ausdrücke)

Um alle Zeichen lebender Sprachen in ein und derselben Kodierung unterzubringen, wurde Unicode (www.unicode.org) geschaffen. Die meisten Programme und Betriebssysteme sind heute in der Lage, Unicode-Zeichen zu verarbeiten und korrekt darzustellen. Der ursprüngliche Unicode verwendet 16 Bits pro Zeichen; damit sind 216 = 65 536 Symbole darstellbar. Der aktuelle Unicode (Version 6.0) verwendet sogar 20 Bits, doch sehr viele Plätze sind noch nicht vergeben. Die meisten Texte (Deutsch, Englisch, Französisch) kommen jedoch mit viel weniger Zeichen aus. Daher entstand die Idee, diese häufigsten Zeichen auch nur mit 8 Bits (= ein Byte) darzustellen.

Die UTF-8 Kodierung -- die obige Komprimierung umsetzt -- ist wie folgt definiert:

  • Zeichen mit einem (Unicode) Wert < 128 werden in einem Byte gespeichert (dabei bleibt das erste Bit immer auf 0 (Null): 0xxx xxxx.
  • Zeichen mit einem Wert von 128 bis 2047 werden in zwei Byte gespeichert: 110x xxxx, 10xx xxxx. Dabei beginnt das erste Byte mit zwei Einsen gefolgt von einer Null und fünf Bits für die "Nutzdaten". Das zweite Byte startet mit "10" und sechs Nutzdaten-Bits. Somit sind elf Nutzdaten-Bits vorhanden. Damit können 211 Zeichen dargestellt werden.
  • Analog verhält es sich mit Zeichen im Bereich 2048 bis 65 535. Diese werden in drei Byte mit sechzehn Nutzdaten-Bits wie folgt gespeichert: 1110 xxxx, 10xx xxxx, 10xx xxxx.

Diese Aufgabe ist ohne Programmieren lösbar: Welche Zeichen verbergen sich hinter den folgenden Zahlen? Schreiben Sie die Zahlen zunächst binär (mit je 8 Binärziffern) auf, suchen Sie anschließend die "Nutz-Bits" und errechnen Sie daraus die Zahl des kodierten Zeichens, das Sie abschließend unter www.unicode.org nachschlagen.

  • 64
  • 80
  • 194, 190
  • 195, 139
  • 239, 172, 129
  • 226,  137,  136

0 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

4 Lösung(en)

# Ausgabe der Unicode Zeichen
def unicode1(a):
    c=unichr(a)
    print c

def unicode2(a,b):
    s1=bin(a)
    s2=bin(b)
    s3=s1[5:10]
    s4=s2[4:10]
    s5=s3+s4
    w=int(s5,2)
    c=unichr(w)
    print c
    
def unicode3(a,b,c):
    s1=bin(a)
    s2=bin(b)
    s3=bin(c)
    s4=s1[6:10]
    s5=s2[4:10]
    s6=s3[4:10]
    s7=s4+s5+s6
    w=int(s7,2)
    c=unichr(w)
    print c
    

unicode1(64)
unicode1(80)
unicode2(194,190)
unicode2(195,139)
unicode3(239,172,129)
unicode3(226,137,136)

                

Lösung von: Martin Guggisberg (Universität Basel / PH FHNW)

package ch.programmieraufgaben.utf;

import java.util.*;

public class UTF8 {
  public static void main(String[] args) {
	new UTF8().top();
  }
  
  void top() {
	List<Integer> zahlen  = eingabeDezimal();
	char  zeichen = utf8(zahlen);
	System.out.println("Das gesuchte Zeichen ist " + zeichen);
  }
  
  char utf8(List<Integer> zahlen) {
	if(1 == zahlen.size()) {
      return utf8(zahlen.get(0));
	}
	if(2 == zahlen.size()) {
		return utf8(zahlen.get(0), zahlen.get(1));
	}
	if(3 == zahlen.size()) {
		return utf8(zahlen.get(0), zahlen.get(1), zahlen.get(2));
	}
	
	return 0;
  }

  char utf8(int c) {
	  if(c < 128) {
		  return (char) c;
	  }
	  else return 0; // error
  }
  
  char utf8(int c1, int c2) {
	if(! checkForStartWith110(c1)) {
		return 0; // error: c1 muss mit 110... beginnen
	}
	if(! checkForStartWith10(c2)) {
		return 0; // error: c2 muss mit 10 beginnen
	}
	int val = c2 & 0x3F;
	val = val + (c1 & 0x1F) * 64;
	return (char) val;
  }

  char utf8(int c1, int c2, int c3) {
	 if(! checkForStartWith1110(c1)) {
		 return 0; // must start with 1110
	 }
	 if(! checkForStartWith10(c2)) {
		 return 0; // c2 must start with 10
	 }
	 if(! checkForStartWith10(c3)) {
		 return 0; // c3 must also start with 10
	 }
	 int val = c3 & 0x3F;
	 val = val + (c2 & 0x3F) * 64;
	 val = val + (c1 & 0x0F) * 4096; 
	 return (char) val;
  }

  boolean checkForStartWith1110(int c) {
	  return 0xE0 == (c & 0xF0);
  }

  boolean checkForStartWith110(int c) {
	return ((0xE0 & c) == 0xC0);
  }

  boolean checkForStartWith10(int c) {
	return ((0xC0 & c) == 0x80);
  }

  List<Integer> eingabeDezimal() {
	 System.out.println("Bitte Zahlen dezimal mit Kommata abgetrennt eingeben.");
	 String eingabe = new Scanner(System.in).next();
	 StringTokenizer st = new StringTokenizer(eingabe, ",");
	 ArrayList<Integer> res = new ArrayList<Integer>();
	 while(st.hasMoreTokens()){
	    res.add(Integer.parseInt(st.nextToken()));
	 }
	 return res;
  }
}

                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

function utfByteLookup(arr) {
  let bits = [],
      chk = [];
  for (let i of arr) bits.push(i.toString(2).padStart(8, '0'));
  bits = bits.join('').split('');
  if (arr.length == 1)
    if (bits.shift() != '0') return undefined;
  if (arr.length == 2) {
    chk = chk.concat(bits.splice(0, 3), bits.splice(5, 2)).join('');
    if (chk != '11010') return undefined;
  }
  if (arr.length == 3) {
    chk = chk.concat(
      bits.splice(0, 4), bits.splice(4, 2), bits.splice(10, 2)
    ).join('');
    if (chk != '11101010') return undefined;
  }
  return String.fromCharCode(parseInt(bits.join(''), 2));
}

// test
for (let i of [
  [64], [80],
  [194, 190], [195, 139],
  [239, 172, 129], [226,  137,  136]
]) console.log( utfByteLookup(i) );
                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

// C++ 20 | VS-2022
// hier eine C++ - Umsetzung inspiriert durch die Java-Lösung :)
#include <iostream>
#include <optional>
#include <vector>
#include <io.h>
#include <fcntl.h>
using uint = unsigned;

struct utf_type {
    uint chr_1;
    std::optional<uint> chr_2{ std::nullopt };
    std::optional<uint> chr_3{ std::nullopt };
};

const auto check_10{ [](uint i) noexcept { return (0xC0 & i) == 0x80;  } }; 
const auto check_110{ [](uint i) noexcept { return (0xE0 & i) == 0xC0;  } };
const auto check_1110{ [](uint i) noexcept { return (0xF0 & i) == 0xE0;  } };

auto get_utf8(const utf_type& ut) {
    if (!ut.chr_2 && !ut.chr_3 && ut.chr_1 < 128)
        return char(ut.chr_1);
    else if (!ut.chr_3 && check_110(ut.chr_1) && check_10(*ut.chr_2)) 
        return char(((ut.chr_1 & 0x1F) << 6) + (*ut.chr_2 & 0x3F));
    else if (check_1110(ut.chr_1) && check_10(*ut.chr_2) && check_10(*ut.chr_3)) 
        return char(((ut.chr_1 & 0x0F) << 12) + ((*ut.chr_2 & 0x3F) << 6) + (*ut.chr_3 & 0x3F));
    else 
        return '\0';
}

std::wostream& operator<<(std::wostream& os, const utf_type ut) {
    os << get_utf8(ut);
    return os;
}

const auto print{ [] <typename T>(T t) {
    auto _ = _setmode(_fileno(stdout), _O_U16TEXT);
    for (const auto& i : t)
        std::wcout << i << "\n";
} };

auto main() -> int {
    const std::vector<utf_type>utf{ {64}, {80}, {194, 190}, {195, 139}, {239, 172, 129}, {226, 137, 136} };
    print(utf);
}
                

Lösung von: Jens Kelm (@JKooP)

Verifikation/Checksumme:

  • 64 (@-Zeichen)
  • 80 (großes P)
  • 194, 190 (¾)
  • 195, 139 (Ë)
  • 239, 172, 129 (fi-Ligatur)
  • 226,  137,  136 (Ungefähr-Zeichen: ?)

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 0.25
Schwierigkeit: k.A.
Webcode: v9hy-tsk4
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Zu Aufgabenblatt hinzufügen