Schlagwort: Informatik

CCC-Fahrplan 👍 👎

Pünktlich zum aktuellen Chaos Communication Congress des CCC möchte ich ein kleines Projekt vorstellen.

Meine Variante des CCC-Fahrplans greift auf die XML- und JSON-Dateien des offiziellen Zeitplans zurück, stellt dadurch alle Veranstaltungen (seit 2006) und Sprecher (seit 2013) einheitlich dar und enthält einige Querverweise. Darüber hinaus ermöglichen die Flaggen eine besonders schnelle Sprachzuordnung direkt auf der Startseite.

Zur Schonung der Infrastruktur des CCC werden die Daten zwischengespeichert, sodass die angezeigten Informationen u. U. veraltet sein können. Bitte informiere dich für verbindliche Informationen direkt beim CCC.

Parameter einer Java-Methode per Reflexion ermitteln 👍 👎

Für ein kleines Projekt (mehr dazu in einem separaten Beitrag) war es notwendig, die Parameter von Methoden per Reflexion in Java zu ermitteln. Die entsprechende Funktionalität findet sich im Paket java.lang.reflect.
Parameter einer Java-Methode per Reflexion ermitteln
0102030405060708091011121314151617181920
public static List<Map<String,String>> GetMethodParameterList(    String typeName,    String methodName) throws ClassNotFoundException {    List<Map<String,String>> methodList = new ArrayList<>();
for(Method method : Class.forName(typeName).getMethods()) { if(method.getName().equals(methodName)) { HashMap<String,String> parameterList = new HashMap<>();
for(Parameter parameter : method.getParameters()) { parameterList.put(parameter.getName(), parameter.getType().getCanonicalName()); }
methodList.add(parameterList); } }
return methodList;}
Ähnlich zu LINQ bei C# gibt es für Java sogenannte Streams; wir können obige Implementierung damit beispielsweise wie folgt unter einem funktionalem Paradigma schreiben:
Implementierung mit Java-Streams
010203040506070809101112
public static List<Map<String,String>> GetMethodParameterList(    String typeName,    String methodName) throws ClassNotFoundException {    return Stream.of(Class.forName(typeName).getMethods())        .filter(m -> m.getName().equals(methodName))        .map(m -> Stream.of(m.getParameters()).collect(Collectors.toMap(            k -> k.getName(),            v -> v.getType().getCanonicalName()        )))        .collect(Collectors.toList());}
Die Verwendung gestaltet sich jeweils identisch:
Methode verwenden und Ergebnis auf der Standardausgabe ausgeben
01020304050607
List<Map<String,String>> methodList = GetMethodParameterList(typeName, methodName);
for(Map<String,String> parameterList : methodList) { for(Map.Entry<String,String> parameter : parameterList.entrySet()) { System.out.println(parameter.getValue() + " " + parameter.getKey()); }}
Es gilt schließlich noch eine kleine Besonderheit zu berücksichtigen: Standardmäßig stehen die Bezeichner der Parameter unter Java nicht zur Verfügung, sondern würden schlicht durchnummeriert. Um die tatsächlichen Bezeichner zu erhalten, muss mit der Option -parameters kompiliert werden. Verbreitete Entwicklungsumgebungen wie Eclipse oder NetBeans bieten hierfür entsprechende Einstellungen.

Wir bereits früher angekündigt werde ich zur Reflexion in C# noch einen etwas ausführlicheren Beitrag schreiben und dann dort eine entsprechende Implementierung ähnlicher Funktionalität vorstellen.

Wissen(schaft)spodcasts 👍 👎

In früheren Beiträgen hatte ich bereits ein paar Podcast-Empfehlungen ausgesprochen und auf mein Feedreader-Projekt hingewiesen, welches ebenfalls einige Podcasts aus verschiedenen Themenbereichen bereithält.

Mit diesem Beitrag möchte ich darüber hinaus gerne auf Wissenschaftspodcasts hinweisen. Diese Seite wurde von einigen Podcastern aus dem Bereich der Wissenschafts- und Wissensvermittlung ins Leben gerufen. Zu den Gründern gehören u. a. auch Nicolas Wöhrl von methodisch inkorrekt und Markus Völter von omega tau – beides Podcasts, die ich schon seit sehr langer Zeit verfolge und auch hier bereits beworben habe.

Die von den genannten und weiteren Personen eröffnete Seite bietet nun eine Sammlung verschiedenster Podcasts aus den Bereichen Wissen und Wissenschaft. Das Themenspektrum ist breit abgedeckt und reicht von Archäologie, Geschichte und Technik über Astronomie, Forschung im Allgemeinen und Speziellen bis hin zu Mathematik und Naturwissenschaften. Ich gehe also davon aus, dass für (fast) alle meiner – sicherlich hauptsächlich technisch interessierten – Besucher etwas dabei sein dürfte. Ihr könnt darüber hinaus auch neue Vorschläge einreichen.

Da mir die Vermittlung von Wissen und das Gespräch über wissenschaftliche Erkenntnisse persönlich äußerst wichtige Angelegenheiten sind, würde ich mich sehr freuen, wenn ihr etwas Passendes findet und die Seite(n) weiterempfehlt. Der Vollständigkeit wegen möchte ich abschließend noch kurz darauf hinweisen, dass ich mit den genannten Seiten in keiner weiteren Verbindung außer als Zuhörer einiger Podcasts stehe.

Base64-Kodierung mit C# 👍 👎

Zur verlustfreien Speicherung und Übertragung von Binärdateien als Text kommt häufig die Base64-Kodierung zum Einsatz. C# unterstützt die (De-)Kodierung dieser Daten in ihrer üblichen Darstellungsform als Zeichenkette sehr komfortabel über die beiden Methoden Convert.ToBase64String und Convert.FromBase64String:
Base64-Konvertierung
01020304
byte[] input = Encoding.UTF8.GetBytes("Hällö!");   // [72, 195, 164, 108, 108, 195, 182, 33]
string base64 = Convert.ToBase64String(input); // "SMOkbGzDtiE="byte[] output = Convert.FromBase64String(base64); // [72, 195, 164, 108, 108, 195, 182, 33]
Die verbreitete Darstellung mit Zeilenumbrüchen nach jeweils 76 Zeichen wird durch die Option Base64FormattingOptions.InsertLineBreaks ermöglicht.

Spannender als mit einer einfachen Zeichenkette ist dieses Vorgehen natürlich bei komplexen Dateien, wie sie beispielsweise im Zusammenhang mit X.509-Zertifikaten auftreten. Praktisch ist dies, da die kodierte Zeichenkette nur noch aus lesbaren ASCII-Zeichen besteht und folglich keine Probleme mit Zeichensätzen zu erwarten sind. Darüber hinaus können derart kodierte Grafiken beispielsweise direkt in Webseiten eingebettet werden.

Offensichtlich sollte dieses Verfahren jedoch nicht zur "Verschlüsselung" sensibler Daten verwendet werden.

(De-)Kompression mit C# 👍 👎

Zwar ist Speicher heutzutage üblicherweise keine Mangelware mehr, dennoch kann sich die Komprimierung großer Datenmengen, beispielsweise zur Übertragung, lohnen. C# bietet dazu einige Möglichkeiten, so unter anderem zur Arbeit mit ZIP-Archiven. Zu diesen möchte ich jedoch in einem separaten Beitrag kommen und stattdessen zeigen, wie sich mit der DeflateStream-Klasse beliebige Daten(-ströme) (de-)komprimieren lassen:
(De-)Komprimierung von Rohdaten
01020304050607080910111213141516171819202122232425
  // Daten komprimierenpublic static byte[] Compress(byte[] data) {    using(MemoryStream inStream = new MemoryStream(data)) {        using(MemoryStream outStream = new MemoryStream()) {            using(DeflateStream deflate = new DeflateStream(outStream, CompressionMode.Compress)) {                inStream.CopyTo(deflate);            }
return outStream.ToArray(); } }}
// Daten dekomprimierenpublic static byte[] Decompress(byte[] data) { using(MemoryStream inStream = new MemoryStream(data)) { using(MemoryStream outStream = new MemoryStream()) { using(DeflateStream deflate = new DeflateStream(inStream, CompressionMode.Decompress)) { deflate.CopyTo(outStream); }
return outStream.ToArray(); } }}
Um beispielsweise komplette Dateien effizient zu (de-)komprimieren, kann wie folgt vorgegangen werden:
(De-)Komprimierung von Dateien
010203040506070809101112131415161718192021
  // Datei komprimierenpublic static void CompressFile(string inputPath, string outputPath) {    using(FileStream inStream = File.OpenRead(inputPath)) {        using(FileStream outStream = File.OpenWrite(outputPath)) {            using(DeflateStream deflate = new DeflateStream(outStream, CompressionMode.Compress)) {                inStream.CopyTo(deflate);            }        }    }}
// Datei dekomprimierenpublic static void DecompressFile(string inputPath, string outputPath) { using(FileStream inStream = File.OpenRead(inputPath)) { using(FileStream outStream = File.OpenWrite(outputPath)) { using(DeflateStream deflate = new DeflateStream(inStream, CompressionMode.Decompress)) { deflate.CopyTo(outStream); } } }}
Sofern zusätzlich verschlüsselt werden soll, worauf ich in einem separaten Beitrag näher eingehen möchte, ist eine sinnvolle Reihenfolge zu beachten. Diese trägt zwar, abgesehen von kleineren Umständen bei unberechtigten Entschlüsselungsversuchen, nicht wesentlich zur Sicherheit an sich bei – wohl aber zur erzielbaren Kompression.

Die (verlustfreie) Datenkompression basiert hauptsächlich auf Redundanzreduktion. Es werden also Muster der Eingabe erkannt und kompakter kodiert. Derartige Muster sollten nach einer ordnungsgemäßen Verschlüsselung jedoch nicht auftreten, d. h. die Ausgabe wirkt ohne Schlüssel weitestgehend zufällig. Verschlüsselte Daten lassen sich entsprechend schlecht komprimieren und so lässt sich sogar recht einfach prüfen, ob eine Verschlüsselung grobe Fehler aufweist – nämlich genau dann, wenn eine signifikante Kompression des Chiffrats möglich ist.

Konkret bedeutet dies also für die Praxis üblicherweise, zuerst zu komprimieren und danach zu verschlüsseln.

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche