Freitag, 19. Januar 2018

Ω = 42

5 Tage habe ich gebraucht, bis ich zu dieser Lösung gekommen bin. 42, die Antwort auf die Frage nach dem Leben, dem Universum und dem ganzen Rest, da hätte ich auch früher draufkommen können. Das meinte jedenfalls Dörte ...

Die Formel hexadezimal auszuwerten war kein großes Problem. Ich kam damit auf 1FD6085D7BA77420A7F600D825E6785 (hexadezimal) oder 2644836816426492714330131537535592325 (dezimal).
Beides war aber nicht die Lösung, da musste noch was Spezielles dahinterstecken. An dieser Zahl konnte ich aber nichts Besonderes entdecken:
  • Ich habe die Hexadezimal-Darstellung als Dateiinhalt interpretiert. Es hätte ja ein kleines Bild sein können. Erfolglos.
  • Ich habe beide Ziffernfolgen auf Regelmäßigkeiten und Muster untersucht - aber daraus bin ich nicht schlau geworden.
  • Für EAN-Codes (die Codes auf den Produkten an der Supermarktkasse) waren die Ziffernfolgen zu lang.
Ich mailte meine Erkenntnisse an Björn und er meinte nur, ich wäre nahe dran und ich würde nur eine Kleinigkeit in der Formel übersehen. Ich guckte auf die Formel und dachte: Na klar!
 Ω(<Ausdruck>)*2+1
Das Omega könnte ja zur Formel gehören! Nach etwas Suchen fand ich in der englischen Wikipedia, dass Ω(n) in der Zahlentheorie genutzt wird, um die Anzahl der Primfaktoren von n zu bezeichnen. Also habe ich ein Programm geschrieben und schnell ermittelt:
1322418408213246357165065768767796162
= 2*97*6816589733057970913221988498803073
Ob 6816589733057970913221988498803073 eine Primzahl ist, weiß ich nicht. Aber wenn sie einen Teiler hat, dann ist der größer als 100 Millionen und damit konnte ich die Größe von Ω(<Ausdruck>) ganz gut abschätzen: Es muss 3,4 oder 5 sein. Aber auch dieses führte nicht zur Lösung.

Björns Antwort auf meinen Bericht:

Vergiss Omega. Das ist Prosa.
Primzahlen falscher Weg.

Hinweis: Welche Rechenoperationen sind in der Formel? Was wird damit erreicht?


Welches Detail sollte ich also übersehen haben? *, +, (, ) waren eindeutig, das Ω gehörte nicht dazu, Hexadezimalziffern waren richtig - da blieben nur noch die eckigen Klammern. Die hätte man auch als Array-Index interpretieren können, aber hier gab es ja gar keinen Array. Meine Überlegungen in diese Richtung müssen Björn fast wahnsinnig gemacht haben!

Heute habe ich Björn angerufen und er hat mich aufgefordert, die Zahl in Binärdarstellung aufzuschreiben und die Ziffern zu zählen. Das ergab plötzlich Sinn und der Rest war Fleißarbeit:

1111111010110000010000101110101111011101001110111010000100000101001111111011000000000110110000010010111100110011110000101

Das sind 121 Ziffern, eine Quadratzahl. Man kann sie also auch im 11*11-Raster aufschreiben:

1 1 1 1 1 1 1 0 1 0 1
1 0 0 0 0 0 1 0 0 0 0
1 0 1 1 1 0 1 0 1 1 1
1 0 1 1 1 0 1 0 0 1 1
1 0 1 1 1 0 1 0 0 0 0
1 0 0 0 0 0 1 0 1 0 0
1 1 1 1 1 1 1 0 1 1 0
0 0 0 0 0 0 0 0 1 1 0
1 1 0 0 0 0 0 1 0 0 1
0 1 1 1 1 0 0 1 1 0 0
1 1 1 1 0 0 0 0 1 0 1

Da kann man doch Strukturen erkennen, oder? Ich hielt es zuerst für eine Position in Conways Game of Life . Das erwies sich aber schnell als Irrtum. Bei der grafischen Darstellung, wobei eine 1 durch einen schwarzen Block und eine 0 durch einen weißen Block dargestellt wurde, entdeckte ich die Ähnlichkeit zu einem QR-Code:

Mit etwas Recherche war schnell klar, dass es sich um einen Micro-QR-Code mit der Breite 11 handelt. Jetzt nur noch schnell mit dem Handy scannen und fertig, dachte ich. Probiert es ruhig mal, die meisten QR-Code-Apps beherrschen leider keinen Micro-QR-Code. Ich habe 4 verschiedene Apps sowie 3 Online-QR-Code-Reader ausprobiert und hatte keinen Erfolg. Deshalb habe ich mich an das Entschlüsseln per Hand gemacht (siehe diese Informationen), aber es mangels exakter Spezifikation nicht vollständig geschafft. Schließlich hat nach 3 Stunden QR-Code-Fummelei ein heruntergeladenenes Windows-Programm die Arbeit übernommen:

Anmerkung:
Dieser Eintrag wurde nacherfasst am 23.1.2018.

Montag, 15. Januar 2018

Gewürze und Knobeleien

Gestern waren Dörte und ich bei Elke und Björn zum Rätseln eingeladen. Kurz nach 11 Uhr trafen wir uns zum Brunch in dem Lokal, in dem Elke letztes Jahr ihren runden Geburtstag gefeiert hatte. Elke und Björn waren vorher noch nie zum Brunch hier und wir als Reinbeker natürlich auch nicht. Man kann das sehr empfehlen - das Buffet war superlecker und die Atmosphäre so, dass man sich gut unterhalten konnte. Thema war zunächst nicht das Rätseln, sondern unsere Trainingswanderung vom Tag zuvor.

Gegen 13 Uhr wurde es dann aber ernst: Wir siedelten in Elkes und Björns Wohnung um und ich wurde mit etwas konfrontiert, was ich überhaupt nicht erwartet hatte: Elke hatte ein Gewürzrätsel vorbereitet!

Auf dem Tisch standen 24 Schälchen mit verschiedenen Gewürzen und es reichte nicht, das gesuchte Gewürz durch Google herauszufinden. Ich musste durch Riechen oder Schmecken auch herausfinden, in welchem Schälchen sich das Gewürz befand, damit ich die entsprechende Nummer für die Lösung notieren konnte.

Am schwierigsten war die Suche nach 4 Gewürzen, die in einem englischen Liebeslied vorkommen. Zum Glück hat Dörte mich unterstützt und so waren wir nach etwa 90 Minuten fertig. Genauer gesagt: Wir waren mit Elkes Aufgaben fertig. Denn jetzt kamen die von Björn vorbereiteten Knobeleien an die Reihe. Das war nichts für Dörte, sie hat sich nach dem Kaffee trinken mit selbst gebackenem Kuchen mit Elke zum Video-Gucken zurückgezogen. Die beiden schmachteten Cary Grant in "Jede Frau braucht einen Engel" an, während ich mir den Kopf über neue Sudokuformen zerbrach, die nur mit Buntstiften zu lösen waren.
Das Knobeln zog sich ganz schön hin. Björn hat gegen 21 Uhr noch was vom Asia-Imbiss geholt, damit wir nicht verhungerten. Als wir uns gestern Abend gegen 22:30 Uhr verabschiedeten, waren immer noch 2 Rätsel übrig. Zum Abschied gab Björn mir den Zettel mit der finalen Lösungsformel mit - nicht ohne vorher genau meine bisherigen Teilergebnisse zu kontrollieren, weil die Formel sonst nicht funktioniere.
Irgendwas Besonderes muss da also dran sein, obwohl es nur wie eine ganz normale hexadezimale Rechnung aussieht. Ich habe jedenfalls noch eine Nachtschicht eingelegt und war heute früh um 1:30 Uhr mit den letzten beiden Rätseln fertig. Um die Formel kümmere ich mich morgen!

Anmerkung:
Dieser Eintrag wurde nacherfasst am 22.1.2018.

Montag, 1. Januar 2018

Pole pole!

An diesem Neujahrswochenende wollte ich nach den Teilerfolgen auch das ganze Rätsel lösen. Wenn man mit einem Buch, einer definierten Textstelle und einem Blatt voller Zahlen dasteht, dann kommt man mit ein wenig Recherche schnell auf die Vermutung, dass es sich um die Beale-Chiffre handelt.

Dahinter steckt eine abenteuerliche Geschichte von einem Schatz, den ein gewisser Thomas J. Beale in den Jahren 1820/22 versteckt haben soll. In insgesamt 3 verschlüsselten Botschaften hat er den Schatz und vermutlich seinen Lageort beschrieben. Von diesen 3 Botschaften konnte man bis heute nur die zweite entschlüsseln, wobei die Nummern in die Anfangsbuchstaben des soundsovielten Wortes der amerikanischen Unabhängigkeitserklärung übersetzt wurden. Niemand weiß bis heute, welchen Text man für die Entschlüsselung der anderen beiden Botschaften braucht. Deshalb weiß man bisher auch nur was in dem Schatz vergraben ist, aber nicht, wo der Schatz liegt!
Aufgrund der Vermutung einer Beale-Chiffre habe ich schnell den Anfang des Kapitels mit der Textstelle abgeschrieben. Mit ein wenig Excel konnte ich dann schnell einen Entschlüsselungsversuch nach Beale starten. Leider zunächst ohne Erfolg. Obwohl ich 6 Varianten probiert habe: Start bei der Überschrift oder beim Kapitelanfang oder bei der Textstelle und Trekking-Stöcke als ein oder zwei Worte.

Da ich mir eigentlich sicher war, dass es sich um eine Beale-Chiffre handelte, mailte ich mein Ergebnis noch kurz vor dem Aufbruch in den Silvesterurlaub an Kai. Er und Nathalie fragten sich, was schief gelaufen sei (sie hatten ihr Exemplar des Buches an mich verliehen). Kurz darauf fand ich den Fehler: Ich hatte ziemlich am Anfang des Kapitels einen Satz schlicht vergessen und dadurch hat sich alles verschoben. Ich erhielt jetzt folgenden Text:

LiebeRJAnwirwuenScHEnDiRallesGutEzumgeBUrTsTaGaUchwenneSJeTzTveRmUTLichschOnLangenacHTRaeGlicHistnUnhAstdüjaEinEnteiLdEsRaeTsElsschongeloestUnddAnnveRmUtlichauchdieHOmMAgeAnUnseREnToLLengemeiNSAMenkiLiManJaRouRlAubErkAnntferTiGbistduAllErDinGsnochnichtUNteRdeRUrlwwwPUnKthUfEnbacHPunktccSlAshJAnscachegEhteswEiterviELeRFolg

Einerseits freute ich mich, den dritten Teil auch gelöst zu haben. Andererseits wartete ein neues Rätsel auf mich unter www.hufenbach.cc/janscache. Als erstes wartete dort die folgende Frage auf mich:

"Wie lautete die Begründung für langsamen Seitenaufbau auf der Webseite der TK am 12. Dezember 1996?"

Wie sollte ich das am Wochenende beantworten, ohne an meinem Arbeitsplatz bei der TK zu recherchieren? Ja, ich erinnerte mich, dass wir im Dezember 1996 Antwortzeitprobleme in unserem System hatten und ich deshalb sogar Dörte und die Kinder beim Weihnachtsmärchen im Ohnsorgtheater versetzt hatte. Aber das war TKeasy, unser System für die Mitarbeiter, und nicht unser Internetauftritt.

Ich fragte mich dann, wo Kai und Nathalie die Antwort gefunden haben könnten. Sie waren damals ja vermutlich noch im Grundschulalter und hatten sicherlich noch nichts von der TK gehört. Dann fiel mir das Internet-Archiv ein. Dort werden regelmäßig viele Websites gesichert, damit sie der Nachwelt erhalten bleiben.
Ich fand dort auch den Snapshot einer Webseite der TK aus dem Dezember 1996 - noch unter der alten Adresse www.tk-online.de:
Als ich dort auf Hilfe und dann auf "World Wide Wait?" klickte, hatte ich meine Antwort. Als nächstes erwartete ich eine ähnlich Frage. Stattdessen erhielt ich die Aufforderung "Break the code!"

Ich fragte bei Kai an, ob ich wirklich den Code auf www.hufenbach.cc analysieren und brechen sollte und er antwortete, dass mir sein Webserver sonst wohl nicht das Lösungswort verraten würde. Inzwischen war es schon Samstagabend und ich schaffte es nur noch, ein paar Debug-Versuche zu machen aber keinen ernsthaften Angriff (für die Nicht-Techniker: Drückt mal F12 im Browser, wenn Ihr wissen wollt, was wirklich unter der Haube im Browser passiert!).

Ich war mit Dörte über das  Wochenende nach St. Michaelisdonn gefahren, damit sie bei etwas Nordseeluft endlich ihre Erkältung los wird. Der Ort war ein wenig trostlos, das Zimmer auch und draußen roch es nach Pferdemist. Das war trotzdem OK, denn wir sind Silvester nach Friedrichskoog und Büsum gefahren und ansonsten hat Dörte sich gesund geschlafen. Dadurch hatte ich am Silvesternachmittag und -abend viel Zeit, mir den Code anzusehen. Hier mal ein Ausschnitt:

var _0x84eb=['getElementById','innerHTML','wTRST','Ygu','solution','erJKn','round','gfYsO','random','length','value','KlVYM','rkFAr','substr','MaM','wAvic','CxQmG','ObZSk','bWkge','wGLSu','http://www.hufenbach.cc/janscache/php/submit.php','IkghT','?answer=','then','aBt','rWLGT','rETAz','json','OYj','qpr','LEzbU','yLngF','question'];(function(a,c){var b=function(b){while(--b){a['push'](a['shift']());}};b(++c);}(_0x84eb,0x76));var _0xb84e=function(a,c){a=a-0x0;var b=_0x84eb[a];return b;};function init(){var a={'wGLSu':function b(a){return a();}};a[_0xb84e('0x0')](loadData);}function loadData(c){var b={'IkghT':_0xb84e('0x1'),'ehLIq':function d(a,b){return a(b);}};let a=b[_0xb84e('0x2')];if(c){a=a+_0xb84e('0x3')+b['ehLIq'](encodeURI,c);}fetch(a)[_0xb84e('0x4')](function(b){var a={'rWLGT':function c(a,b){return a===b;},'pArZF':_0xb84e('0x5'),'rETAz':function d(a){return a();}};if(a[_0xb84e('0x6')]('wOv',a['pArZF'])){a[_0xb84e('0x7')](loadData);}else{return b[_0xb84e('0x8')]();}})

Man nennt das obfuskierten Code, also bewusst unleserlich gemachten Code. Damit will man verhindern, dass Leute, die den Programmcode ausführen können, ihn auch kopieren und modifizieren können. Zusätzlich gab es 2 Funktionen, die völlig abgefahrene Zeichenkombinationen wie diese enthielten:

var key = aesjs.util.convertStringToBytes((![]+[])[+!+[]]+[!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+!+[]+[+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[]) ...

Diese Kombinationen aus den Zeichen ()[]+! waren seitenlang. Wenn ich runterscrollte, ergaben sich Effekte optischer Täuschung, denn es gab plötzlich Farbränder! Und das sollte ich alles verstehen?
Nein, das musste auch anders gehen!  Jetzt wollte ich Kai mit seinen eigenen Waffen schlagen!

Durch das Debuggen hatte ich schon herausgefunden, dass im Prinzip nur 2 Bytes, die sich aus der Antwort berechnen ließen, an den Server übertragen wurden. Das gab also nur 65536 Möglichkeiten, die konnte ich doch einfach durch ein Skript absetzen lassen und dann die Serverantworten auf meiner Festplatte speichern und durchsuchen. Ganz so leicht hat es mir Kai aber nicht gemacht: Die beiden Bytes waren mit viel Sicherheitsbrimborium aufgepeppt, damit der Webserver prüfen kann, ob hier jemand geschummelt hat. So ein Request sah ungefähr so aus:

answer=gxLx8rcl6l7lorNxVgVwyA==U1NVWQ==

Wenn man für dieselben 2 Bytes noch einmal den Server anfragte, dann sah der Request schon wieder anders aus, weil ein Zufallswert in die Berechnung einfloss. Ich habe nun die Berechnungsvorschrift für das Ermitteln der 2 Bytes aus der Antwort auf etwas ganz Einfaches geändert und dann einfach Kais Original-Sicherheitsbrimborium aufgerufen. Frei nach dem Motto: Ich versteh es nicht, aber Kai wird schon dafür gesorgt haben, dass der Server das als richtig anerkennt.  Jetzt konnte ich gezielt alle 65536 möglichen Requests erzeugen.

Der Rest war Fleißarbeit: Die Rechenpower meines Notebooks war nicht sehr groß, ich musste deshalb das Skript in 16 Blöcken zu je 4096 möglichen Eingaben erzeugen. Das bedeutete jeweils 3 Minuten Dödelarbeit und dann 15 Minuten Warten - perfekt für einen Silvesterabend mit kranker Frau im Bett, Picknick im Gästezimmer und Dinner for One, Charlie Chaplin und Ohnsorg im Fernseher. Es war ein spezielles Silvester, das wir nicht so schnell vergessen werden.

Um 1 Uhr früh war mein Skript erstellt und ich habe es gestartet, bevor ich mich schlafen legte. Gegen 7 Uhr am Neujahrsmorgen war es fertig und ich habe die 65536 Ergebnisdateien auf meiner 
Festplatte nach der Größe sortiert. Es gab genau 2 Dateien mit abweichender Größe: "Break the code!" und die Lösung!

So ganz eindeutig war die Lösung dann doch nicht: Zuerst habe ich ein Lösungswort mit 58959 Bytes Länge versucht. Ich hätte lieber gleich die einfache Variante mit einer Länge von 16 Bytes versuchen sollen ...

Das war bisher das komplexeste Rätsel, danke an Kai und Nathalie. Der Bezug zu unserem gemeinsamen Urlaub in Afrika hat mir sehr gefallen. Als Gruß sage ich nur 5895 x pole pole

Anmerkungen:
Dieser Eintrag wurde nacherfasst am 5.1.2018.
Bei dem gruseligen Code aus den Zeichen ()[]!+ handelt es sich um JSFuck, eine esoterische Programmiersprache, die gültiges Javascript ist!