# Copyright (c) 2025 Martin Kayser (tebarius) # Licensed under the MIT License. See LICENSE file in the project root. from itertools import chain # für primfaktoren zerlegung import helper import pandas as pd from urllib.parse import unquote as urllib_parse_unquote # für nak-nak def funktion_mit_karte(text,param): """Verarbeitet Text und liefert Daten für eine Karte (z.B. Potsdam Zentrum).""" # Beispiel: Fester Punkt (Potsdam) daten = pd.DataFrame({'lat': [52.4006], 'lon': [13.0590]}) ausgabe_text = f"Folgende Koordinate wurde gefunden: {daten.iloc[0].lat}, {daten.iloc[0].lon}" ausgabe_text += f' \n text: {text} \n parameter: {param}\n' return ausgabe_text, daten def cesar_all(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Cesar-Verschiebe-Chiffre\n" "Von der eingegebenen Zeichenkette werden, " "alle möglichen Verschiebungen gemäß der " "Cesarchiffre generiert und ausgegeben. " "Sonderzeichen und Zahlen werden unverändert " "wiedergegeben.") else: abcgross = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" abcklein = "abcdefghijklmnopqrstuvwxyz" txt = eingabetext ausgabe = "" for r in range(1, 27): atxt = "" for i in txt: if i.upper() not in abcgross: atxt = atxt + i # nicht codierbare Zeichen direkt zur Ausgabe bitte! continue abc = abcgross if i == i.lower(): abc = abcklein for j in range(26): if i == abc[j]: if j + r >= 26: atxt = atxt + abc[j + r - 26] else: atxt = atxt + abc[j + r] ausgabe += f"__{r:02}:__ {atxt} \n" return ausgabe def buchstabenwortwert(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Buchstabenwortwerte ermitteln\n" "Diese Funktion berechnet den Buchstabenwert " "der eingegeben Zeichenkette. (A=1 B=2 .... " "Ä=27 Ö=28 Ü=29 ß=30) Bei mehreren durch " "Leerzeichen getrennten Wörtern wird auch " "für jedes einzelne Wort der Wortwert errechnet. " "Desweiteren wird die Quersumme und die iterierte " "Quersumme des Gesamtbuchstabenwertes als auch für " "jedes Wort das Buchstabenwertprodukt und das " "Gesamtbuchstabenwertprodukt ermittelt.") else: ausgabe = "" bw = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, 'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, 'P': 16, 'Q': 17, 'R': 18, 'S': 19, 'T': 20, 'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26, 'Ä': 27, 'Ö': 28, 'Ü': 29, 'SS': 30} wortsumme = 0 wortprodukt = 1 atxt = "" az = "" eworttxt = "" ewortptxt = "" banzahla = 0 banzwtxt = "" einzelworte = eingabetext.split() for wort in einzelworte: ewortsumme = 0 ewortprod = 1 banzahlw = 0 ewtr = False for b in wort: if b.upper() not in bw: atxt = atxt + b + "=0 " az = az + "0," continue else: ewtr = True ewortprod *= bw[b.upper()] ewortsumme += bw[b.upper()] wortsumme += bw[b.upper()] wortprodukt *= bw[b.upper()] atxt = atxt + b + "=" + str(bw[b.upper()]) + " " az = az + str(bw[b.upper()]) + "," banzahla += 1 banzahlw += 1 banzwtxt = banzwtxt + str(banzahlw) + "/" eworttxt = eworttxt + str(ewortsumme) + "/" if not ewtr: ewortptxt = ewortptxt + "0/" else: ewortptxt = ewortptxt + str(ewortprod) + "/" ausgabe += atxt + " \n" ausgabe += '| | |\n' ausgabe += '|----|----|\n' ausgabe += "|_Buchstabenwerte:_|" ausgabe += az[0:-1] + "|\n" ausgabe += "|_Buchstabenwortwerte:_|" ausgabe += eworttxt[0:-1] + "|\n" ausgabe += "|_Summe aller Buchstabenwerte:_|" ausgabe += str(wortsumme) + "|\n" ausgabe += "|_Quersumme der Summe aller Buchstabenwerte / iterierte Quersumme:_|" ausgabe += str(helper.q_sum(wortsumme)) + " / " + str(helper.iq_sum(wortsumme)) + "|\n" ausgabe += "|_Buchstabenanzahl pro Wort:_|" ausgabe += banzwtxt[0:-1] + "|\n" ausgabe += "|_Gesamtanzahl aller Buchstaben:_|" ausgabe += str(banzahla) + "|\n" ausgabe += "|_Wortprodukte(0 wenn kein Buchstabe gefunden):_|" ausgabe += ewortptxt[0:-1] + "|\n" ausgabe += "|_Buchstabenwert-Produkt:(Nullen werden ignoriert):_|" ausgabe += str(wortprodukt) + "|\n" return ausgabe def buchstabenwert_zu_text(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") bw = {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z', 27: 'ä', 28: 'ö', 29: 'ü', 30: 'ß'} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Buchstabenwerte zu Text\n" " Die eingegebenen Buchstabenwerte werden in die entsprechenden Buchstaben umgewandelt." " (A=1 B=2 .... Ä=27 Ö=28 Ü=29 ß=30) Als Trennungszeichen zwischen den Zahlen sind folgende" " Zeichen erlaubt: | , _ . - / ; , und Leerzeichen. Bei Verwendung von Leerzeichen sollten" " möglichst nur 1 Leerzeichen zwischen den Zahlen verwendet werden (überzählige Leerzeichen" " werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!\n" else: if ausz not in bw: return "Die eingegebene Zahl ist kein gültiger Buchstabenwert!\n" else: return bw[ausz] else: ausgabe_text = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z) except ValueError: ignor = ignor + str(z) + " " else: if az in bw: atxt = atxt + bw[az] else: ignor = ignor + str(z) + " " if ignor != "": ausgabe_text += "_Achtung folgendes wurde ignoriert:_ \n" ausgabe_text += ignor + " \n \n" ausgabe_text += "_umgewandelte Zeichen:_ \n" ausgabe_text += atxt return ausgabe_text def zeichenkette_reverse(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Zeichenkette rückwärts\n" "Diese Funktion gibt die eingegebene Zeichenkette von hinten nach vorn gelesen aus.") else: return eingabetext[::-1] def zeichenanzahl(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Zeichenzählen\n" "Es wird das Vorkommen jedes einzelnen Zeichens gezählt und ausgegeben. Achtung! Leerzeichen," " Tabulatorzeichen und Zeilenumbrüche werden nur vor dem letzten sichtbaren Zeichen gezählt!!!") else: ausgabetext = "" anzahl = {} for b in eingabetext: if b in anzahl: anzahl[b] = anzahl[b] + 1 else: anzahl[b] = 1 s = [] for key in anzahl: s.append(key) s.sort() ausgabetext += f"Es wurden {len(anzahl)} unterschiedliche Zeichen gefunden. \n" ausgabetext += "| Zeichen | Anzahl |\n|----|----|\n" for i in s: if ord(i) == 9: ausgabetext += f"|TAB|{anzahl[i]}|\n" elif ord(i) == 32: ausgabetext += f"|SPACE|{anzahl[i]}|\n" elif ord(i) == 10: ausgabetext += f"|LINEFEED| = {anzahl[i]}|\n" else: ausgabetext += f"|{i}|{anzahl[i]}|\n" return ausgabetext def quersummen(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Quersumme(n)\n" " Von den eingegebenen Zahlen werden die Quersummen und iterierten Quersummen errechnet und ausgegeben." " Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: | , _ . - / ; , und" " Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den Zahlen" " verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: return f"_Quersumme:_ {helper.q_sum(ausz)} \n_iterierte Quersumme:_ {helper.iq_sum(ausz)}" else: ausgabetext = "" txt = eingabetext.split(se) qtxt = "" iqtxt = "" ignor = "" for z in txt: try: az = int(z) except ValueError: ignor = ignor + str(z) + " " else: qtxt = qtxt + str(helper.q_sum(az)) + "/" iqtxt = iqtxt + str(helper.iq_sum(az)) + "/" if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_Quersummen:_ \n" ausgabetext += qtxt[:-1] + " \n \n" ausgabetext += "_iterierte Quersummen_ \n" ausgabetext += iqtxt[:-1] return ausgabetext def einschluss_count(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Einschlüsse zählen\n" "Es werden die Einschlüsse in Buchstaben und Ziffern gezählt. Neben der Anzahl der Einschlüsse für" " jeden einzelnen Buchstaben, für jedes Wort und die gesammte Eingabe ermittelt. Da es sich bei der" " Zahl 4 je nach Schreibweise um eine Zahl mit oder ohne Einschluß handeln kann, werden beide Varianten" "berücksichtigt. !!! Hier ist Klein- und Großschreibung wichtig, denn z.B. b=1 aber B=2 !!!") else: bw = "ADOPQRabdegopq690" wortsummenliste_ohne = [] wortsummenliste_mit = [] wortliste = eingabetext.split() for wort in wortliste: wz_ohne = 0 wz_mit = 0 for b in wort: if b == "4": wz_mit += 1 if b == "B" or b == "8": wz_ohne += 2 wz_mit += 2 elif b in bw: wz_mit += 1 wz_ohne += 1 wortsummenliste_ohne.append(wz_ohne) wortsummenliste_mit.append(wz_mit) ausgabetext = "__mit 4__ \n" ausgabetext += "_insgesamt gefundene Einschlüsse:_ " ausgabetext += f"{sum(wortsummenliste_mit)} \n" ausgabetext += "_Einschlüsse pro Wort:_ " for z in wortsummenliste_mit: ausgabetext += f"{z} " ausgabetext += " \n \n" ausgabetext += "__ohne 4__ \n" ausgabetext += "_insgesamt gefundene Einschlüsse:_ " ausgabetext += f"{sum(wortsummenliste_ohne)} \n" ausgabetext += "_Einschlüsse pro Wort:_ " for z in wortsummenliste_ohne: ausgabetext += f"{z} " return ausgabetext def morse_to_abc(eingabetext): alphabet = {".-": "A", "-...": "B", "-.-.": "C", "-..": "D", ".": "E", "..-.": "F", "--.": "G", "....": "H", "..": "I", ".---": "J", "-.-": "K", ".-..": "L", "--": "M", "-.": "N", "---": "O", ".--.": "P", "--.-": "Q", ".-.": "R", "...": "S", "-": "T", "..-": "U", "...-": "V", ".--": "W", "-..-": "X", "-.--": "Y", "--..": "Z", ".----": "1", "..---": "2", "...--": "3", "....-": "4", ".....": "5", "-....": "6", "--...": "7", "---..": "8", "----.": "9", "-----": "0", "--.--": "Ñ", "..-..": "É", ".-..-": "È", ".--.-": "À", "..--": "Ü", "---.": "Ö", ".-.-": "Ä", "..--.-": "_", ".--.-.": "@", "..--..": "?", "-...-": "=", "-.-.-.": ";", "---...": ":", "-..-.": "/", ".-.-.-": ".", "-....-": "-", "--..--": ",", ".-.-.": "+", "-.--.-": ")", "-.--.": "(", ".----.": "'", "...--..": "ß" } eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Morsecode zu Text\n" "Die Eingabe des Morsecodes hat wie folgt zu erfolgen: - für lang und . für kurz, zwischen den " "Buchstaben ein Leerzeichen und als Worttrennung ein / wobei davor und danach ein Leerzeichen steht. " "Für unbekannte Morsecodes erscheint in der Ausgabe ein #.") else: morse = eingabetext.split() atxt = "" for sign in morse: if sign == "/": atxt = atxt + " " elif sign not in alphabet: atxt = atxt + "#" else: atxt = atxt + alphabet[sign] return atxt def abc_to_morse(eingabetext): alphabet = {".-": "A", "-...": "B", "-.-.": "C", "-..": "D", ".": "E", "..-.": "F", "--.": "G", "....": "H", "..": "I", ".---": "J", "-.-": "K", ".-..": "L", "--": "M", "-.": "N", "---": "O", ".--.": "P", "--.-": "Q", ".-.": "R", "...": "S", "-": "T", "..-": "U", "...-": "V", ".--": "W", "-..-": "X", "-.--": "Y", "--..": "Z", ".----": "1", "..---": "2", "...--": "3", "....-": "4", ".....": "5", "-....": "6", "--...": "7", "---..": "8", "----.": "9", "-----": "0", "--.--": "Ñ", "..-..": "É", ".-..-": "È", ".--.-": "À", "..--": "Ü", "---.": "Ö", ".-.-": "Ä", "..--.-": "_", ".--.-.": "@", "..--..": "?", "-...-": "=", "-.-.-.": ";", "---...": ":", "-..-.": "/", ".-.-.-": ".", "-....-": "-", "--..--": ",", ".-.-.": "+", "-.--.-": ")", "-.--.": "(", ".----.": "'", "...--..": "SS" } umkehr_alpha = {v: k for k, v in alphabet.items()} # Alphabet mit getauschten key und values generieren eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Morsecode\n" "Eingabetext wird als Morsecode ausgegeben. Nicht kodierbare Zeichen erscheinen unverändert " "in der Ausgabe.") else: atxt = "" for b in eingabetext: if b == " ": atxt = atxt + "/ " elif b.upper() not in umkehr_alpha: atxt = atxt + b + " " else: atxt = atxt + umkehr_alpha[b.upper()] + " " return atxt def rot5(eingabetext): ro5 = {"0": "5", "1": "6", "2": "7", "3": "8", "4": "9", "5": "0", "6": "1", "7": "2", "8": "3", "9": "4"} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### ROT 5\n" "ROT 5 bezeichnet eine Verschiebechiffrierung, bei welcher die Ziffern 0-9 um je 5 Stellen " "verschoben werden. Aus 0 wird 5, aus 1 wird 6, aus 7 wird 2,usw. Kodieren und Dekodieren " "geschieht hier mit ein und derselben Funktion, alle Zeichen die keine Ziffern sind werden " "unverändert wiedergegeben.") else: atxt = "" for z in eingabetext: if z not in ro5: atxt = atxt + z else: atxt = atxt + ro5[z] return atxt def rot13(eingabetext): ro13 = {'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 'G': 'T', 'H': 'U', 'I': 'V', 'J': 'W', 'K': 'X', 'L': 'Y', 'M': 'Z', 'N': 'A', 'O': 'B', 'P': 'C', 'Q': 'D', 'R': 'E', 'S': 'F', 'T': 'G', 'U': 'H', 'V': 'I', 'W': 'J', 'X': 'K', 'Y': 'L', 'Z': 'M'} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### ROT 13\n" "ROT 13 bezeichnet eine Verschiebechiffrierung, bei welcher die 26 Buchstaben (A-Z) um genau " "13 Stellen verschoben werden. Da dies genau die Hälfte des Alphabets ist, wird z.B. aus einem " "A ein N und aus einem N ein A und somit wird über die selbe Funktion sowohl kodiert als auch " "dekodiert. Die Klein- und Großschreibung bleibt erhalten und alle Zeichen die keine Buchstaben " "sind werden unverändert wiedergegeben.") else: atxt = "" for z in eingabetext: if z.upper() not in ro13: atxt = atxt + z elif z.lower() == z: a = ro13[z.upper()] atxt = atxt + a.lower() else: atxt = atxt + ro13[z.upper()] return atxt def rot18(eingabetext): ro18 = {'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S', 'G': 'T', 'H': 'U', 'I': 'V', 'J': 'W', 'K': 'X', 'L': 'Y', 'M': 'Z', 'N': 'A', 'O': 'B', 'P': 'C', 'Q': 'D', 'R': 'E', 'S': 'F', 'T': 'G', 'U': 'H', 'V': 'I', 'W': 'J', 'X': 'K', 'Y': 'L', 'Z': 'M', "0": "5", "1": "6", "2": "7", "3": "8", "4": "9", "5": "0", "6": "1", "7": "2", "8": "3", "9": "4"} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### ROT 18\n" "ROT 18 ist eigentlich nix anderes als, daß hier ROT 5 mit ROT 13 kombiniert wird. Die Buchstaben " "A-Z werden um 13 Stellen verschoben und die Ziffern 0-9 um 5 Stellen. Alle sonstigen Zeichen " "bleiben unverändert und die Klein- oder Großschreibung bleibt auch erhalten, und auch hier " "kodiert/dekodiert ein und dieselbe Funktion.") else: atxt = "" for z in eingabetext: if z.upper() not in ro18: atxt = atxt + z elif z.lower() == z: a = ro18[z.upper()] atxt = atxt + a.lower() else: atxt = atxt + ro18[z.upper()] return atxt def rot47(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### ROT 47\n" "Bei ROT47 geschieht eigentlich nix anderes als bei ROT5 oder ROT13 nur das hier die druckbaren " "ASCII-Zeichen mit den Werten 33-126(dezimal) zur Auswahl stehen, also nahezu alle Zeichen die auf " "eine Standardtastatur aufgedruckt sind. Das Ergebnis ist aber deutlich unlesbarer als z.B. bei " "ROT13. Alle weiteren Zeichen (z.B. ÄÖÜß) werden unverändert wiedergegeben und auch hier " "kodiert/dekodiert ein und dieselbe Funktion.") else: x = [] for i in eingabetext: j = ord(i) if 33 <= j <= 126: x.append(chr(33 + ((j + 14) % 94))) else: x.append(i) return f"```\n{''.join(x)}\n```" def ascii_to_dez(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Dezimalzahlen\n" "Der eingegebene Text wird in Dezimalzahlen umgewandelt.") else: z = [] for i in eingabetext: z.append(str(ord(i))) return ' '.join(z) def dez_to_ascii(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Dezimalzahlen zu Text\n" "Die eingegebenen Dezimalzahlen werden in die entsprechenden UNICODE-Zeichen umgewandelt. Als " "Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: | , _ . - / ; , und Leerzeichen. " "Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den Zahlen verwendet " "werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: return chr(ausz) else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z) except ValueError: ignor = ignor + str(z) + " " else: atxt = atxt + chr(az) if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_umgewandelte Zeichen:_ \n" ausgabetext += atxt return ausgabetext def ascii_to_hex(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Hexadezimalzahlen\n" "Der eingegebene Text wird in Hexadezimalzahlen umgewandelt.") else: z = [] for i in eingabetext: hexstr = ("{:X}".format(ord(i))) # großes X für Hex in Großbuchstaben z.append(hexstr) return ' '.join(z) def hex_to_ascii(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Hexadezimalzahlen zu Text\n" "Die eingegebenen Hexadezimalzahlen werden in die entsprechenden UNICODE-Zeichen umgewandelt. " "Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: | , _ . - / ; , und " "Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den " "Zahlen verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 16) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: return chr(ausz) else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z, 16) except ValueError: ignor = ignor + str(z) + " " else: atxt = atxt + chr(az) if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_umgewandelte Zeichen:_ \n" ausgabetext += atxt return ausgabetext def ascii_to_octal(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Octalzahlen\n" "Der eingegebene Text wird in Octalzahlen umgewandelt.") else: z = [] for i in eingabetext: z.append("{:o}".format(ord(i))) return ' '.join(z) def octal_to_ascii(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Octalzahlen zu Text\n" "Die eingegebenen Octalzahlen werden in die entsprechenden UNICODE-Zeichen umgewandelt. Als " "Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: | , _ . - / ; , und Leerzeichen. " "Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den Zahlen verwendet " "werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 8) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: return chr(ausz) else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z, 8) except ValueError: ignor = ignor + str(z) + " " else: atxt = atxt + chr(az) if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_umgewandelte Zeichen:_ \n" ausgabetext += atxt return ausgabetext def ascii_to_bin16(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Binärzahlen\n" "Der eingegebene Text wird in Binärzahlen mit einer festgelegten Breite von 16bit (16 Zeichen) " "umgewandelt.") else: z = [] for i in eingabetext: z.append("{:0>16b}".format(ord(i))) return ' '.join(z) def ascii_to_bin8(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Binärzahlen\n" "Der eingegebene Text wird in Binärzahlen mit einer festgelegten Breite von 8bit (8 Zeichen) " "umgewandelt.") else: z = [] for i in eingabetext: if ord(i) > 255: return ("Sorry der Eingabetext enthält Zeichen,welche sich nicht mit 8 bit in binär darstellen " "lassen!") z.append("{:0>8b}".format(ord(i))) return ' '.join(z) def bin_to_ascii(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Binärzahlen zu Text\n" "Die eingegebenen Binärzahlen werden in die entsprechenden UNICODE-Zeichen umgewandelt. Als " "Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: | , _ . - / ; , und " "Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den Zahlen " "verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 2) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: return chr(ausz) else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z, 2) except ValueError: ignor = ignor + str(z) + " " else: atxt = atxt + chr(az) if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_umgewandelte Zeichen:_ \n" ausgabetext += atxt return ausgabetext def zahlwortsuche_de(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Zahlwortsuche DE 0-12\n" "Diese Funktion versucht deutsche Zahlworte zwischen 0 und 12 in einem Text aufzuspüren. Da alle " "Zeichen ignoriert werden, welche keine Buchstaben sind, werden auch Zahlwörter gefunden welche sich " "z.B. über zwei Worte verteilen.") else: zahlen = ["null", "eins", "zwei", "drei", "vier", "fünf", "fuenf", "sechs", "sieben", "acht", "neun", "zehn", "elf", "zwölf", "zwoelf", "zwanzig", "hundert", "tausend"] ntxt = "" abc = "abcdefghijklmnopqrstuvwxyzäöüß" for b in eingabetext: if b.lower() not in abc: continue ntxt = ntxt + b.lower() for z in zahlen: if z.lower() in ntxt: ntxt = ntxt.replace(z.lower(), "-" + z.upper() + "_") atxt = "" tt = False for b in ntxt: if b == "-": tt = True continue if b == "_": tt = False atxt = atxt + " " if tt: atxt = atxt + b if atxt == "": return "Leider keine Zahlwörter gefunden!" else: ausgabetext = "_Gefundene Zahlwörter:_ \n" ausgabetext += atxt + " \n \n" ausgabetext += "_Eingangstext:_ \n" ausgabetext += ntxt return ausgabetext def zahlwortsuche_en(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Zahlwortsuche EN 0-15\n" "Diese Funktion versucht englische Zahlworte zwischen 0 und 15 in einem Text aufzuspüren. " "Da alle Zeichen ignoriert werden, welche keine Buchstaben sind, werden auch Zahlwörter gefunden " "welche sich z.B. über zwei Worte verteilen.") else: zahlen = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "fourty", "sixty", "seventy", "eighty", "ninety", "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "twenty", "thirty", "fifty"] ntxt = "" abc = "abcdefghijklmnopqrstuvwxyz" for b in eingabetext: if b.lower() not in abc: continue ntxt = ntxt + b.lower() for z in zahlen: if z.lower() in ntxt: ntxt = ntxt.replace(z.lower(), "-" + z.upper() + "_") atxt = "" tt = False for b in ntxt: if b == "-": tt = True continue if b == "_": tt = False atxt = atxt + " " if tt: atxt = atxt + b if atxt == "": return "Leider keine Zahlwörter gefunden!" else: ausgabetext = "_Gefundene Zahlwörter:_ \n" ausgabetext += atxt + " \n \n" ausgabetext += "_Eingangstext:_ \n" ausgabetext += ntxt return ausgabetext def kenny_kodieren(eingabetext): alphabet = {"a": "mmm", "b": "mmp", "c": "mmf", "d": "mpm", "e": "mpp", "f": "mpf", "g": "mfm", "h": "mfp", "i": "mff", "j": "pmm", "k": "pmp", "l": "pmf", "m": "ppm", "n": "ppp", "o": "ppf", "p": "pfm", "q": "pfp", "r": "pff", "s": "fmm", "t": "fmp", "u": "fmf", "v": "fpm", "w": "fpp", "x": "fpf", "y": "ffm", "z": "ffp", "ä": "mmmmpp", "ö": "ppfmpp", "ü": "fmfmpp", "ß": "fmmfmm", "A": "Mmm", "B": "Mmp", "C": "Mmf", "D": "Mpm", "E": "Mpp", "F": "Mpf", "G": "Mfm", "H": "Mfp", "I": "Mff", "J": "Pmm", "K": "Pmp", "L": "Pmf", "M": "Ppm", "N": "Ppp", "O": "Ppf", "P": "Pfm", "Q": "Pfp", "R": "Pff", "S": "Fmm", "T": "Fmp", "U": "Fmf", "V": "Fpm", "W": "Fpp", "X": "Fpf", "Y": "Ffm", "Z": "Ffp", "Ä": "Mmmmpp", "Ö": "Ppfmpp", "Ü": "Fmfmpp" } eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Kennyspeak kodieren\n" "Hilfe sie haben Kenny getötet.. ach nee er kann ja noch seine unverständlichen m p f -Laute von " "sich geben und hier geht es darum normalen Text in genau diese Laute umzusetzen, wo jedem Buchstaben " "A-Z eine 3 Zeichen-Kombination zugeordnet ist die sich aus m,p,f zusammensetzt.(a=mmm h=mfp x=fpf)") else: atxt = "" for b in eingabetext: if b in alphabet: atxt = atxt + alphabet[b] else: atxt = atxt + b return atxt def kenny_dekodieren(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Kennyspeak dekodieren\n" "Wie? Du verstehst Kenny's mpf-Gebrabbel nicht? Na gut da kann ich helfen!! Nicht kennifiziertes " "wird unverändert ausgegeben.") else: return helper.unkennify(eingabetext) def kenny_raten(eingabetext): wbk = {"000": "a", "001": "b", "002": "c", "010": "d", "011": "e", "012": "f", "020": "g", "021": "h", "022": "i", "100": "j", "101": "k", "102": "l", "110": "m", "111": "n", "112": "o", "120": "p", "121": "q", "122": "r", "200": "s", "201": "t", "202": "u", "210": "v", "211": "w", "212": "x", "220": "y", "221": "z" } eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### KENNYspeak raten\n" "Diese Funktion dient zum dekodieren von kennyfizierten Texten, bei denen die 3 Buchstaben mpf " "vertauscht oder durch andere Zeichen ersetzt wurden. Hierzu werden vor der Dekodierung die 3 " "häufigsten Zeichen im Text ermittelt und alle anderen Zeichen entfernt bevor die 6 möglichen " "Lösungen ausgegeben werden. (Falls zum kodieren die Zahlen 0,1 oder 2 verwendet wurden, werden " "sie durch Buchstaben a,b,c.. ersetzt)") else: wtxt = eingabetext.replace(chr(9),"").replace(chr(32),"").replace(chr(10),"").lower() # erstmal leerzeichen, tab, linefeed raus und alles klein anzahl = {} # restliche zeichen zählen und in ein wörterbuch for c in wtxt: if c in anzahl: anzahl[c] = anzahl[c] + 1 else: anzahl[c] = 1 s = [] # zum Sortieren lieber eine liste for key in anzahl: s.append([anzahl[key], key]) s.sort(reverse=True) abc3 = [s[0][1], s[1][1], s[2][1]] # die 3 häufigsten Zeichen im Text wären gefunden cwtxt = "" for b in wtxt: # alles raus außer den 3 häufigsten Zeichen if b not in abc3: continue cwtxt = cwtxt + b abca = ["a", "b", "c", "d"] # falls 0,1,2 verwendet wurden in a, b, c... ändern if "0" in abc3 or "1" in abc3 or "2" in abc3: for i in range(3): if abc3[i] in ["0", "1", "2"]: for j in abca: if j in abc3: continue else: cwtxt = cwtxt.replace(abc3[i], j) abc3[i] = j break ausgabetext = "" for p in helper.all_perms(abc3): txt0 = cwtxt.replace(p[0], "0") txt1 = txt0.replace(p[1], "1") txt2 = txt1.replace(p[2], "2") atxt = "" for i in range(0, len(txt2), 3): tri = txt2[i:i + 3] if tri in wbk: atxt = atxt + wbk[tri] ausgabetext += f"_{p}_ \n" ausgabetext += f"{atxt} \n \n" return ausgabetext def primzahlalphabet_dekodieren(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Primzahlalphabet dekodieren\n" "Hier können Primzahlen kleiner als 1 Million in Buchstaben umgewandelt werden. Es wird dabei davon " "ausgegangen, daß den Primzahlen wiederholend die Buchstaben A-Z zugeordnet werden,2=A 3=B 5=C 7=D " "11=E ... 97=Y 101=Z 103=A 107=B ... usw.") else: grenze = 1000000 primes = helper.primzahlliste(grenze) pdict = {} bz = 65 for p in primes: if bz == 91: bz = 65 pdict[p] = chr(bz) bz += 1 seperator = ("|,", "_", ".", "-", "/", ";", ",") se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; . / - _ | oder Leerzeichen) erkannt!" else: if ausz in pdict: return pdict[ausz] else: return eingabetext + " ist keine Primzahl oder größer als 1 Million!" else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" ignor = "" for z in txt: try: az = int(z) except ValueError: ignor = ignor + str(z) + " " else: if az in pdict: atxt = atxt + pdict[az] else: ignor = ignor + str(z) + " " if ignor != "": ausgabetext += "_ignoriert wurde:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_umgewandelte Zahlen:_ \n" ausgabetext += atxt return ausgabetext def primzahlpruefen(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Primzahl prüfen\n" "Für eine eingegebene Zahl wird überprüft, ob es sich um eine Primzahl handelt. Ist die eingegebene " "Zahl eine Primzahl wird auch informiert, die wievielte Primzahl es ist. Zahlen über 1,299,709 (der " "100,000. Primzahl) werden abgelehnt.") else: try: ausz = int(eingabetext) except ValueError: return "Keine Zahl erkannt!" else: if ausz > 1299709: return ("Sorry, aber ich mag nur die ersten 100,000 Primzahlen, das sind Zahlen bis maximal " "1,299,709 !") primes = helper.primzahlliste(1299710) if ausz not in primes: return f"{ausz:,} ist keine Primzahl" else: return f"{ausz:,} ist die {primes.index(ausz) + 1:,}. Primzahl" def nte_primzahl(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### n.te Primzahl\n" "Du willst wissen wie z.B. die 1,000. Primzahl lautet, dann bist du hier genau richtig. Die Funktion " "liefert maximal die 100,000. Primzahl.") else: try: ausz = int(eingabetext) except ValueError: return "Keine Zahl erkannt!" if ausz > 100000: return "Sorry, aber ich mag nur die ersten 100,000 Primzahlen, das sind Zahlen bis maximal 1,299,709 !" else: primes = helper.primzahlliste(1299710) return f"Die {ausz:,}. Primzahl lautet: {primes[ausz - 1]:,}" def primfaktoren(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Primfaktorenzerlegung\n" "Für die eingegebene Zahl werden die Primfaktoren ermittelt und ausgegeben. Sollte die Zahl einen " "Primfaktoren haben, welcher größer als 100 Millionen ist, wird die Suche abgebrochen, da die Suche " "sonst zu lange dauert. Die Funktion läßt sich damit also auch, bei Zahlen kleiner als 200 Millionen, " "dazu benutzen um festzustellen, ob die eingegebene Zahl eine Primzahl ist.") else: try: n = int(eingabetext) except ValueError: return "Es konnte leider keine Zahl erkannt werden." faktoren = [] for i in chain([2], range(3, n // 2 + 1, 2)): if i > 100000000: return ("Sorry, aber die Primfaktorensuche wurde abgebrochen, da mindestens 1 Faktor größer als " "100 Millionen ist.") while n % i == 0: faktoren.append(i) n = n // i if i > n: break out = f"_Die Zahl {eingabetext} hat folgende Primfaktoren:_ \n" if not faktoren: return f"Die Zahl {eingabetext} ist eine Primzahl!!" else: for z in faktoren: out += str(z) + ", " return out[:-2] def dez_to_hex_oct_bin(eingabetext): seperator = ("|,", "_", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Dezimal zu HEX, Octal, Binär\n" "Die eingegebenen dezimalen Ganzzahlen werden in die entsprechenden hexadezimalen, octalen und " "binären Zahlen umgerechnet. Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: " "| , _ / ; , und Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen " "zwischen den Zahlen verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte " "Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; / _ | oder Leerzeichen) erkannt!" else: return "Dez: {0:} \nHEX: {0:X} \nOCT: {0:o} \nBIN: {0:b}".format(ausz) else: ausgabetext = "" txt = eingabetext.split(se) deztxt, hextxt, octtxt, bintxt, ignor = "", "", "", "", "" for z in txt: try: az = int(z) except ValueError: ignor = ignor + str(z) + " " else: deztxt = deztxt + str(az) + "/" hextxt = hextxt + "{:X}".format(az) + "/" octtxt = octtxt + "{:o}".format(az) + "/" bintxt = bintxt + "{:b}".format(az) + "/" if ignor != "": ausgabetext += f"_Achtung nicht erkannte Zeichen:_ {ignor} \n" ausgabetext += f"_DEZ:_ {deztxt[:-1]} \n" ausgabetext += f"_HEX:_ {hextxt[:-1]} \n" ausgabetext += f"_OCT:_ {octtxt[:-1]} \n" ausgabetext += f"_BIN:_ {bintxt[:-1]} \n" return ausgabetext def hex_to_dez_oct_bin(eingabetext): seperator = ("|,", "_", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Hexadezimal zu Dezimal, Octal, Binär\n" "Die eingegebenen hexadezimalen Zahlen werden in die entsprechenden dezimalen, octalen und binären " "Zahlen umgerechnet. Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: " "| , _ / ; , und Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen " "zwischen den Zahlen verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte " "Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 16) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; / _ | oder Leerzeichen) erkannt!" else: return "HEX: {0:X} \nDez: {0:} \nOCT: {0:o} \nBIN: {0:b}".format(ausz) else: ausgabetext = "" txt = eingabetext.split(se) deztxt, hextxt, octtxt, bintxt, ignor = "", "", "", "", "" for z in txt: try: az = int(z, 16) except ValueError: ignor = ignor + str(z) + " " else: deztxt = deztxt + str(az) + "/" hextxt = hextxt + "{:X}".format(az) + "/" octtxt = octtxt + "{:o}".format(az) + "/" bintxt = bintxt + "{:b}".format(az) + "/" if ignor != "": ausgabetext += f"_Achtung nicht erkannte Zeichen:_ {ignor} \n" ausgabetext += f"_HEX:_ {hextxt[:-1]} \n" ausgabetext += f"_DEZ:_ {deztxt[:-1]} \n" ausgabetext += f"_OCT:_ {octtxt[:-1]} \n" ausgabetext += f"_BIN:_ {bintxt[:-1]} \n" return ausgabetext def oct_to_hex_dez_bin(eingabetext): seperator = ("|,", "_", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Octal zu HEX, Dezimal, Binär\n" "Die eingegebenen octalen Zahlen werden in die entsprechenden hexadezimalen, dezimalen und binären " "Zahlen umgerechnet. Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: " "| , _ / ; , und Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen " "zwischen den Zahlen verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte " "Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 8) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; / _ | oder Leerzeichen) erkannt!" else: return "OCT: {0:o} \nHEX: {0:X} \nDez: {0:} \nBIN: {0:b}".format(ausz) else: ausgabetext = "" txt = eingabetext.split(se) deztxt, hextxt, octtxt, bintxt, ignor = "", "", "", "", "" for z in txt: try: az = int(z, 8) except ValueError: ignor = ignor + str(z) + " " else: deztxt = deztxt + str(az) + "/" hextxt = hextxt + "{:X}".format(az) + "/" octtxt = octtxt + "{:o}".format(az) + "/" bintxt = bintxt + "{:b}".format(az) + "/" if ignor != "": ausgabetext += f"_Achtung nicht erkannte Zeichen:_ {ignor} \n" ausgabetext += f"_OCT:_ {octtxt[:-1]} \n" ausgabetext += f"_HEX:_ {hextxt[:-1]} \n" ausgabetext += f"_DEZ:_ {deztxt[:-1]} \n" ausgabetext += f"_BIN:_ {bintxt[:-1]} \n" return ausgabetext def bin_to_hex_dez_oct(eingabetext): seperator = ("|,", "_", "/", ";", ",") eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Binär zu HEX, Dezimal, Octal\n" "Die eingegebenen binären Zahlen werden in die entsprechenden hexadezimalen, dezimalen und octalen " "Zahlen umgerechnet. Als Trennungszeichen zwischen den Zahlen sind folgende Zeichen erlaubt: " "| , _ / ; , und Leerzeichen. Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen " "zwischen den Zahlen verwendet werden (überzählige Leerzeichen werden sonst als nicht erkannte " "Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext, 2) except ValueError: return "Keine Zahl oder gültiges Trennzeichen (, ; / _ | oder Leerzeichen) erkannt!" else: return "BIN: {0:b} \nHEX: {0:X} \nDez: {0:} \nOCT: {0:o}".format(ausz) else: ausgabetext = "" txt = eingabetext.split(se) deztxt, hextxt, octtxt, bintxt, ignor = "", "", "", "", "" for z in txt: try: az = int(z, 2) except ValueError: ignor = ignor + str(z) + " " else: deztxt = deztxt + str(az) + "/" hextxt = hextxt + "{:X}".format(az) + "/" octtxt = octtxt + "{:o}".format(az) + "/" bintxt = bintxt + "{:b}".format(az) + "/" if ignor != "": ausgabetext += f"_Achtung nicht erkannte Zeichen:_ {ignor} \n" ausgabetext += f"_BIN:_ {bintxt[:-1]} \n" ausgabetext += f"_HEX:_ {hextxt[:-1]} \n" ausgabetext += f"_DEZ:_ {deztxt[:-1]} \n" ausgabetext += f"_OCT:_ {octtxt[:-1]} \n" return ausgabetext def abc_to_tomtom(eingabetext): alphabet = {"a": "/ ", "b": "// ", "c": "/// ", "d": "//// ", "e": "/\\\\ ", "f": "//\\\\ ", "g": "///\\\\ ", "h": "/\\\\\\\\ ", "i": "/\\\\\\\\\\ ", "j": "\\\\/ ", "k": "\\\\\\\\/ ", "l": "\\\\\\\\\\\\/ ", "m": "\\\\// ", "n": "\\\\/// ", "o": "/\\\\/ ", "p": "//\\\\/ ", "q": "/\\\\\\\\/ ", "r": "/\\\\// ", "s": "\\\\/\\\\ ", "t": "\\\\\\\\/\\\\ ", "u": "\\\\//\\\\ ", "v": "\\\\/\\\\\\\\ ", "w": "//\\\\\\\\ ", "x": "\\\\\\\\// ", "y": "\\\\/\\\\/ ", "z": "/\\\\/\\\\ " } # schräg aber wir brauchen zum kodieren doppel-doppelte backslashs damit die Ausgabe im Browser passt if eingabetext == "": return ("### Text zu Tomtom\n" "Beim Tomtom Code werden die einzelnen Buchstaben durch Kombinationen von / und \\ dargestellt. " "Zwischen den einzelnen Buchstaben steht ein Leerzeichen zwischen Worten zwei Leerzeichen. Kodiert " "werden, können nur die Buchstaben A-Z.") else: ausgabetext = "" atxt = "" ignor = "" for b in eingabetext: if b == " ": atxt = atxt + " " elif b.lower() not in alphabet: ignor = ignor + b + " " else: atxt = atxt + alphabet[b.lower()] if ignor != "": ausgabetext += "_ignorierte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_kodierter Text:_ \n" ausgabetext += atxt return ausgabetext def tomtom_to_abc(eingabetext): alphabet = {'/': 'A', '//': 'B', '///': 'C', '////': 'D', '/\\': 'E', '//\\': 'F', '///\\': 'G', '/\\\\': 'H', '/\\\\\\': 'I', '\\/': 'J', '\\\\/': 'K', '\\\\\\/': 'L', '\\//': 'M', '\\///': 'N', '/\\/': 'O', '//\\/': 'P', '/\\\\/': 'Q', '/\\//': 'R', '\\/\\': 'S', '\\\\/\\': 'T', '\\//\\': 'U', '\\/\\\\': 'V', '//\\\\': 'W', '\\\\//': 'X', '\\/\\/': 'Y', '/\\/\\': 'Z' } # schräg aber wir brauchen zum kodieren doppel-doppelte backslashs damit die Ausgabe im Browser passt eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Tomtom zu Text\n" "Beim Tomtom Code werden die einzelnen Buchstaben durch Kombinationen von / und \\ dargestellt. " "Zwischen den einzelnen Buchstaben steht ein Leerzeichen zwischen Worten zwei Leerzeichen. Kodiert " "werden, können nur die Buchstaben A-Z.") else: tomtom = eingabetext.replace(" ", " _ ") tomtom = tomtom.split() atxt = "" for sign in tomtom: if sign == "_": atxt = atxt + " " elif sign not in alphabet: atxt = atxt + "#" else: atxt = atxt + alphabet[sign] return atxt def text_to_slashpipe(eingabetext): alphabet = {"a": "| ", "b": "|\\\\ ", "c": "|| ", "d": "|/ ", "e": "\\\\ ", "f": "||\\\\ ", "g": "||| ", "h": "\\\\\\\\ ", "i": "/ ", "j": "|\\\\\\\\ ", "k": "//|| ", "l": "|\\\\/ ", "m": "|\\\\| ", "n": "|/| ", "o": "||/| ", "p": "|\\\\|\\\\ ", "q": "/\\\\ ", "r": "\\\\/ ", "s": "/| ", "t": "|// ", "u": "// ", "v": "||\\\\\\\\ ", "w": "\\\\/|| ", "x": "||/ ", "y": "|||\\\\ ", "z": "|||| " } # jweils doppelte backslashs da python sonst versucht Escapecodes draus zu machen \\ = \ eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Text zu Slash and Pipe\nVergleichbar mit dem Tomtom-Code nur das hier für die Buchstabenkodierung " "auch | eingesetzt wird. Zwischen den einzelnen Buchstaben steht ein Leerzeichen zwischen Worten zwei " "Leerzeichen. Kodiert werden, können nur die Buchstaben A-Z.") else: ausgabetext = "" atxt = "" ignor = "" for b in eingabetext: if b == " ": atxt = atxt + " " elif b.lower() not in alphabet: ignor = ignor + b + " " else: atxt = atxt + alphabet[b.lower()] if ignor != "": ausgabetext += "_ignorierte Zeichen:_ \n" ausgabetext += ignor + " \n \n" ausgabetext += "_kodierter Text:_ \n" ausgabetext += atxt return ausgabetext def slashpipe_to_text(eingabetext): alphabet = {'|': 'A', '|\\': 'B', '||': 'C', '|/': 'D', '\\': 'E', '||\\': 'F', '|||': 'G', '\\\\': 'H', '/': 'I', '|\\\\': 'J', '//||': 'K', '|\\/': 'L', '|\\|': 'M', '|/|': 'N', '||/|': 'O', '|\\|\\': 'P', '/\\': 'Q', '\\/': 'R', '/|': 'S', '|//': 'T', '//': 'U', '||\\\\': 'V', '\\/||': 'W', '||/': 'X', '|||\\': 'Y', '||||': 'Z'} # jeweils doppelte backslashs da python sonst versucht Escapecodes draus zu machen \\ = \ eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Slash and Pipe zu Text\nVergleichbar mit dem Tomtom-Code nur das hier für die Buchstabenkodierung " "auch der | mit eingesetzt wird. Zwischen den einzelnen Buchstaben steht ein Leerzeichen zwischen " "Worten zwei Leerzeichen. Dekodiert werden, können nur die Buchstaben A-Z.") else: tomtom = eingabetext.replace(" ", " _ ") tomtom = tomtom.split() atxt = "" for sign in tomtom: if sign == "_": atxt = atxt + " " elif sign not in alphabet: atxt = atxt + "#" else: atxt = atxt + alphabet[sign] return atxt def periodensystem(eingabetext): seperator = ("|,", "_", ".", "-", "/", ";", ",") pse = {1: "H", 2: "He", 3: "Li", 4: "Be", 5: "B", 6: "C", 7: "N", 8: "O", 9: "F", 10: "Ne", 11: "Na", 12: "Mg", 13: "Al", 14: "Si", 15: "P", 16: "S", 17: "Cl", 18: "Ar", 19: "K", 20: "Ca", 21: "Sc", 22: "Ti", 23: "V", 24: "Cr", 25: "Mn", 26: "Fe", 27: "Co", 28: "Ni", 29: "Cu", 30: "Zn", 31: "Ga", 32: "Ge", 33: "As", 34: "Se", 35: "Br", 36: "Kr", 37: "Rb", 38: "Sr", 39: "Y", 40: "Zr", 41: "Nb", 42: "Mo", 43: "Tc", 44: "Ru", 45: "Rh", 46: "Pd", 47: "Ag", 48: "Cd", 49: "In", 50: "Sn", 51: "Sb", 52: "Te", 53: "I", 54: "Xe", 55: "Cs", 56: "Ba", 57: "La", 58: "Ce", 59: "Pr", 60: "Nd", 61: "Pm", 62: "Sm", 63: "Eu", 64: "Gd", 65: "Tb", 66: "Dy", 67: "Ho", 68: "Er", 69: "Tm", 70: "Yb", 71: "Lu", 72: "Hf", 73: "Ta", 74: "W", 75: "Re", 76: "Os", 77: "Ir", 78: "Pt", 79: "Au", 80: "Hg", 81: "Tl", 82: "Pb", 83: "Bi", 84: "Po", 85: "At", 86: "Rn", 87: "Fr", 88: "Ra", 89: "Ac", 90: "Th", 91: "Pa", 92: "U", 93: "Np", 94: "Pu", 95: "Am", 96: "Cm", 97: "Bk", 98: "Cf", 99: "Es", 100: "Fm", 101: "Md", 102: "No", 103: "Lr", 104: "Rf", 105: "Db", 106: "Sg", 107: "Bh", 108: "Hs", 109: "Mt", 110: "Ds", 111: "Rg", 112: "Cn", 113: "Nh", 114: "Fl", 115: "Mc", 116: "Lv", 117: "Ts", 118: "Og"} um_pse = {v: k for k, v in pse.items()} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Periodensystem: Ordnungszahl<->Symbol\n" "Eingegebenen Ordnungszahlen 1-118 aus dem Periodensystem der Elemente werden in die ihnen zugehörigen " "Elementsymbole umgewandelt und anschließend als Text ausgegeben, außerdem erscheint noch eine Ausgabe " "bei welcher nur die Anfangsbuchstaben der Symbole ausgegeben werden. Werden in der Eingabe Symbole " "(z.B. N, He) erkannt werde diese zusammen mit ihren Ordnungszahlen ausgegeben. Als Trennungszeichen " "zwischen den Zahlen und/oder Symbolen sind folgende Zeichen erlaubt: | , _ . - / ; , und Leerzeichen. " "Bei Verwendung von Leerzeichen sollten möglichst nur 1 Leerzeichen zwischen den Zahlen verwendet " "werden (überzählige Leerzeichen werden sonst als nicht erkannte Zeichen behandelt).") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": try: ausz = int(eingabetext) except ValueError: if eingabetext in um_pse: return str(um_pse[eingabetext]) else: return "Keine gültige Eingabe erkannt!" else: return pse[ausz] else: ausgabetext = "" txt = eingabetext.split(se) atxt = "" atxt2 = "" atxt3 = "" ignor = "" for z in txt: try: az = int(z) except ValueError: if z in um_pse: atxt3 += z + ":" + str(um_pse[z]) + " " else: ignor = ignor + z + " " else: if az in pse: atxt = atxt + pse[az] + " " atxt2 = atxt2 + pse[az][0] else: ignor = ignor + z + " " if ignor != "": ausgabetext += "_Achtung nicht erkannte Zeichen:_ \n" + ignor + " \n \n" if atxt != "": ausgabetext += "_Symbole:_ \n" + atxt + " \n \n" if atxt2 != "": ausgabetext += "_Nur Anfangsbuchstaben:_ \n" + atxt2 + " \n \n" if atxt3 != "": ausgabetext += "_Symbol:Ordnungszahl_ \n" + atxt3 return ausgabetext def naknak_to_text(eingabetext): nakwb = {"Nak": "0", "Naknak": "6", "nanak": "B", "Nanak": "1", "Naknaknak": "7", "naknak": "C", "Nananak": "2", "Nak.": "8", "nak!": "D", "Nanananak": "3", "Naknak.": "9", "nak.": "E", "Nak?": "4", "Naknaknaknak": "A", "naknaknak": "F", "nak?": "5"} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### NakNak to Text\n" "Nak-Nak / Entensprache / Duck Speak ist eine Spaßsprache, welche vom Owner der Website " "[https://schnatterente.net](https://web.archive.org/web/20230807065421/https://www.schnatterente.net/)" " entwickelt wurde. Diese Funktion übersetzt das Geschnatter in verständliche Buchstaben/Zeichen. " "!!Bitte unbedingt die Groß- und Kleinschreibung beibehalten!! Wer diesen Quatsch unbedingt umgekehrt " "übersetzten will, wird wohl etwas suchen müssen, da der Original-Übersetzer, der unter " "http://uebersetzer.schnatterente.net erreichbar war, nicht mehr online ist und ich ganz bestimmt " "keinen hier integrieren werde.") else: txt = eingabetext.split() utxt = "" z = 1 for nak in txt: if nak in nakwb and z == 1: utxt = utxt + "%" + nakwb[nak] z += 1 elif nak in nakwb: utxt = utxt + nakwb[nak] z = 1 atxt = urllib_parse_unquote(utxt) return "_dekodiertes Geschnatter:_ \n" + atxt def navajo_to_text(eingabetext): nabc = {"WOL-LA-CHEE": "A", "BE-LA-SANA": "A", "TSE-NILL": "A", "NA-HASH-CHID": "B", "SHUSH": "B", "TOISH-JEH": "B", "MOASI": "C", "TLA-GIN": "C", "BA-GOSHI": "C", "BE": "D", "CHINDI": "D", "LHA-CHA-EH": "D", "AH-JAH": "E", "DZEH": "E", "AH-NAH": "E", "CHUO": "F", "TSA-E-DONIN-EE": "F", "MA-E": "F", "AH-TAD": "G", "KLIZZIE": "G", "JEHA": "G", "TSE-GAH": "H", "CHA": "H", "LIN": "H", "TKIN": "I", "YEH-HES": "I", "A-CHI": "I", "TKELE-CHO-G": "J", "TKELE-CHO-GI": "J", "AH-YA-TSINNE": "J", "YIL-DOI": "J", "JAD-HO-LONI": "K", "BA-AH-NE-DI-TININ": "K", "KLIZZIE-YAZZIE": "K", "DIBEH-YAZZIE": "L", "AH-JAD": "L", "NASH-DOIE-TSO": "L", "TSIN-TLITI": "M", "BE-TAS-TNI": "M", "NA-AS-TSO-SI": "M", "TSAH": "N", "A-CHIN": "N", "NESH-CHEE": "N", "A-KHA": "O", "TLO-CHIN": "O", "NE-AHS-JAH": "O", "NE-ASH-JAH": "O", "CLA-GI-AIH": "P", "BI-SO-DIH": "P", "BI-SODIH": "P", "NE-ZHONI": "P", "CA-YEILTH": "Q", "GAH": "R", "DAH-NES-TSA": "R", "AH-LOSZ": "R", "DIBEH": "S", "KLESH": "S", "D-AH": "T", "A-WOH": "T", "THAN-ZIE": "T", "SHI-DA": "U", "NO-DA-IH": "U", "A-KEH-DI-GLINI": "V", "GLOE-IH": "W", "AL-NA-AS-DZOH": "X", "AL-AN-AS-DZOH": "X", "TSAH-AS-ZIH": "Y", "BESH-DO-TLIZ": "Z", "BESH-DO-GLIZ": "Z", "BE-TKAH": " "} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Navajo-ABC to Text\n" "Die Sprache der Navajo-Indianer wurde im zweiten Weltkrieg für den verschlüßelten Funkverkehr " "eingesetzt. Vorteile waren, daß nahezu niemand außer Navajo-Volk die Sprache verstand und es keine " "schriftlichen Aufzeichnungen über die Sprache gab. Das Alphabet und die Codewörter wurden dabei von " "den Codesprechern (natürlich Navajo's) auswendig gelernt. Die Dekodierfunktion hier übersetzt das " "Codealphabet (A-Z), bei welchem es auch so ist, daß unterschiedliche Worte für den selben Buchstaben " "stehen, in normalen Text. Leider existieren leicht unterschiedliche Alphabete was die Wörter bzw. " "deren Schreibweise angeht im Netz, mit welchen codiert wird, weshalb ich hier nur die Dekodierung " "anbiete. weitere Codewörter und Erklärungen gibt es z.B. hier: " "https://ww2db.com/other.php?other_id=29 oder hier: " "http://math.ucsd.edu/~crypto/Projects/RobertoSandoval/NavajoWindtalkers.pdf") else: txt = eingabetext.split() atxt = "" for wort in txt: w = wort.upper() if w in nabc: atxt = atxt + nabc[w] return "_dekodierter Text:_ \n" + atxt def pi_suche(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### PI Nachkommastellensuche\n" "Für die eingegebene Zahl/Zahlenreihe X wird versucht die entsprechende X. Nachkommastelle auszugeben " "und das erst Vorkommen der Zahlenreihe X innerhalb der Nachkommastellen von PI " "(3.141592653589793238462643...) zu ermitteln. Aus Performance- und Speicherplatzgründen ist die Suche " "auf die ersten 10 Millionen Nachkommastellen beschränkt.") else: try: piread = open("./data/pi.txt", "r") except FileNotFoundError: return "Sorry es scheint die Datei pi.txt zu fehlen, welche von dieser Funktion benötigt wird." else: pistr = "" for zeile in piread: pistr = pistr + zeile.rstrip() piread.close() pilen = len(pistr) - 2 try: zahlx = int(eingabetext) except ValueError: return "Sorry aber ohne gültige Zahleneingabe funktioniert das nicht!" else: ausgabetext = "_PI (Kreiszahl)_ \n \n" pos = pistr.find(eingabetext) if pilen >= zahlx > 0: ausgabetext += (f"_Die {zahlx}. Nachkommstelle lautet:_ {pistr[zahlx + 1]} \n_20 Stellen ab " f"{zahlx}. Nachkommstelle:_ {pistr[zahlx + 1:zahlx + 21]}... \n \n") else: ausgabetext += f"_Die verwendete pi.txt kennt leider nur {pilen:,} Nachkommstellen._ \n \n" if pos == -1: ausgabetext += f"_Zahlenreihe in {pilen:,} Nachkommastellen nicht zu finden._" else: ausgabetext += (f'erstes Vorkommen von Zahlenfolge "{eingabetext.rstrip()}" ab {pos - 1}. ' f'Nachkommastelle \n20 Stellen ab {pos - 1}. Nachkommstelle: ' f'{pistr[pos:pos + 20]}...') return ausgabetext def euler_suche(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Eulersche Zahl - Nachkommastellensuche\n" "Für die eingegebene Zahl/Zahlenreihe X wird versucht die entsprechende X. Nachkommastelle auszugeben " "und das erst Vorkommen der Zahlenreihe X innerhalb der Nachkommastellen von e " "(2.71828182845904523.....) zu ermitteln. Aus Performance- und Speicherplatzgründen " "ist die Suche auf die ersten 10 Millionen Nachkommastellen beschränkt.") else: try: eread = open("./data/e.txt", "r") except FileNotFoundError: return "Sorry es scheint die Datei e.txt zu fehlen, welche von dieser Funktion benötigt wird." else: estr = "" for zeile in eread: estr = estr + zeile.rstrip() eread.close() elen = len(estr) - 2 try: zahlx = int(eingabetext) except ValueError: return "Sorry aber ohne gültige Zahleneingabe funktioniert das nicht!" else: ausgabetext = "_e (Eulersche Zahl)_ \n \n" pos = estr.find(eingabetext) if elen >= zahlx > 0: ausgabetext += (f"_Die {zahlx}. Nachkommstelle lautet:_ {estr[zahlx + 1]} \n_20 Stellen ab " f"{zahlx}. Nachkommstelle:_ {estr[zahlx + 1:zahlx + 21]}... \n \n") else: ausgabetext += f"_Die verwendete pi.txt kennt leider nur {elen:,} Nachkommstellen._ \n \n" if pos == -1: ausgabetext += f"_Zahlenreihe in {elen:,} Nachkommastellen nicht zu finden._" else: ausgabetext += (f'erstes Vorkommen von Zahlenfolge "{eingabetext.rstrip()}" ab {pos - 1}. ' f'Nachkommastelle \n20 Stellen ab {pos - 1}. Nachkommstelle: ' f'{estr[pos:pos + 20]}...') return ausgabetext def goldener_schnitt_suche(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### phi(Goldener Schnitt) Nachkommastellensuche\n" "Für die eingegebene Zahl/Zahlenreihe X wird versucht die entsprechende X. Nachkommastelle auszugeben " "und das erst Vorkommen der Zahlenreihe X innerhalb der Nachkommastellen von phi " "(1.618033988749894848204586...) zu ermitteln. Aus Performance- und Speicherplatzgründen ist die " "Suche auf die ersten 10 Millionen Nachkommastellen beschränkt.") else: try: phiread = open("./data/phi.txt", "r") except ValueError: return "Sorry es scheint die Datei phi.txt zu fehlen, welche von dieser Funktion benötigt wird." else: phistr = "" for zeile in phiread: phistr = phistr + zeile.rstrip() phiread.close() philen = len(phistr) - 2 try: zahlx = int(eingabetext) except ValueError: return "Sorry aber ohne gültige Zahleneingabe funktioniert das nicht!" else: ausgabetext = "_phi (Goldener Schnitt)_ \n \n" pos = phistr.find(eingabetext) if philen >= zahlx > 0: ausgabetext += (f"_Die {zahlx}. Nachkommstelle lautet:_ {phistr[zahlx + 1]} \n_20 Stellen ab " f"{zahlx}. Nachkommstelle:_ {phistr[zahlx + 1:zahlx + 21]}... \n \n") else: ausgabetext += f"_Die verwendete pi.txt kennt leider nur {philen:,} Nachkommstellen._ \n \n" if pos == -1: ausgabetext += f"_Zahlenreihe in {philen:,} Nachkommastellen nicht zu finden._" else: ausgabetext += (f'erstes Vorkommen von Zahlenfolge "{eingabetext.rstrip()}" ab {pos - 1}. ' f'Nachkommastelle \n20 Stellen ab {pos - 1}. Nachkommstelle: ' f'{phistr[pos:pos + 20]}...') return ausgabetext def anagramm_suche_de(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Anagrammsuche mit Wörterbuch DE\n" "Diese Funktion benutzt eine deutsche Wörterbuchdatei vom Project " "https://sourceforge.net/projects/germandict um zu überprüfen ob sich unter Verwendung __aller__ " "eingegebenen Buchstaben Wörter bilden lassen, welche im Wörterbuch vorkommen.") else: try: wbfile = open("./data/german.dic", "r", encoding="iso-8859-15") # german.dic von https://sourceforge.net/projects/germandict/ except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: eingabezaehl = helper.wortzaehl(eingabetext) ausgabetext = "_gefundene Anagramme:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") if eingabetext.upper() == zeile.upper(): continue if len(eingabetext) != len(zeile): continue if eingabezaehl == helper.wortzaehl(zeile): ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def anagramm_suche_en(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Anagrammsuche mit Wörterbuch EN\n" "Diese Funktion benutzt die englische Wörterliste en_US-large.txt vom Project " "https://sourceforge.net/projects/wordlist um zu überprüfen ob sich unter Verwendung aller " "eingegebenen Buchstaben Wörter bilden lassen, welche im Wörterbuch vorkommen. Dieses Wörterbuch " "kennt übrigens auch viele Wörter mit Apostroph wie z.B. say's.") else: try: wbfile = open("./data/en_US-large.txt", "r", encoding="UTF-8") except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: eingabezaehl = helper.wortzaehl(eingabetext) ausgabetext = "_gefundene Anagramme:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") if eingabetext.upper() == zeile.upper(): continue if len(eingabetext) != len(zeile): continue if eingabezaehl == helper.wortzaehl(zeile): ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def wortsuche_de(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Wortsuche mit Wörterbuch DE\n" "Wer kennt es nicht? Man sucht ein Wort mit einer bestimmten Anzahl an Buchstaben und weiß aber z.B. " "nur den Anfangsbuchstaben und die letzten 3 Buchstaben. Hierbei soll diese Funktion helfen. " "Unbekannte Buchstaben werden dabei einfach durch * ersetzt. Klein-/Großschreibung in der Eingabe " "wird dabei ignoriert. \n" "Beispiel: \n" "Ge*ca**i** -> Geocaching \n" "ge*ca**i** -> Geocaching \n" "T*****dose -> Tupperdose, Tabaksdose" "Diese Funktion nutzt dafür die deutsche Wörterbuchdatei vom Project " "https://sourceforge.net/projects/germandict") else: try: wbfile = open("./data/german.dic", "r", encoding="iso-8859-15") except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_im Wörterbuch gefundene passende Wörter:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") if len(eingabetext) != len(zeile): continue fehler = 0 for c in range(len(eingabetext)): if eingabetext[c] == "*": continue if eingabetext[c].upper() != zeile[c].upper(): fehler += 1 if fehler == 0: ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def wortsuche_en(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### Wortsuche mit Wörterbuch EN\n" "Wer kennt es nicht? Man sucht ein Wort mit einer bestimmten Anzahl an Buchstaben und weiß aber z.B. " "nur den Anfangsbuchstaben und die letzten 3 Buchstaben. Hierbei soll diese Funktion helfen. " "Unbekannte Buchstaben werden dabei einfach durch * ersetzt. Klein-/Großschreibung in der Eingabe " "wird dabei ignoriert. \n" "Beispiel: \n" "Ge*ca**i** -> geocaching \n" "ge*ca**i** -> geocaching \n" "say*s -> say's (Die Wortliste kennt viele Wörter mit Apostroph) \n" "coordinat** -> coordinator, coordinates, coordinated \n" "Diese Funktion nutz dafür die englische Wörterliste en_US-large.txt vom Project " "https://sourceforge.net/projects/wordlist") else: try: wbfile = open("./data/en_US-large.txt", "r", encoding="UTF-8") except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_im Wörterbuch gefundene passende Wörter:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") if len(eingabetext) != len(zeile): continue fehler = 0 for c in range(len(eingabetext)): if eingabetext[c] == "*": continue if eingabetext[c].upper() != zeile[c].upper(): fehler += 1 if fehler == 0: ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def remorse_de(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### RE-Morse DE\n" "Es gibt ja so Leute, die finden es lustig einen Morsecode so aufzuschreiben, daß zwar Wort für Wort " "getrennt wird, aber ansonsten einfach mal die Leerzeichen weggelassen werden. Bei genau solchen " "fiesen Gemeinheiten hilft diese Funktion. Diese Funktion benutzt die deutsche Wörterbuchdatei vom " "Project https://sourceforge.net/projects/germandict \n" "Da eine Abfrage relativ lange dauert gibt es die Möglichkeit ein ca. 100 MB großes remorse-de.dic " "generieren zu lassen, welches ab der nächsten Abfrage dann genutzt wird und wodurch dann nur noch " "ca. 20% der Zeit pro Abfrage benötigt wird. Um die Erstellung zu starten muß das Wort GENERATE " "(Großschreibung beachten!) ins Eingabefeld eingetragen werden und der Funktionsknopf betätigt " "werden.") else: try: wbfile = open("./data/morse-de.dic", "r", encoding="iso-8859-15") # german.dic von https://sourceforge.net/projects/germandict/ except FileNotFoundError: try: testfile = open("./data/german.dic", "r") testfile.close() if eingabetext == "GENERATE": helper.remorse_generate_morsede() return "Remorse-Wörterbuch wurde erzeugt und wird ab dem nächsten Aufruf der Funktion benutzt." else: ausgabetext = ("_Da das Remorse-Wörterbuch noch nicht generiert wurde, wurde das normale_ " "_Wörterbuch für die Suche benutzt, das dauert zwar ca. 5x so lange, aber geht_ " "_auch._ \n" "_Um das Remorse-Wörterbuch zu erzeugen bitte das Wort:_ __GENERATE__ _ins_ " "_Eingabefeld eingeben und die Funktion starten._ \n \n") return ausgabetext + helper.remorse_germandic(eingabetext) except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_der eingegebene Morsecode kann für folgendes stehen:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") mline = zeile.split(",") if eingabetext == mline[0]: ausgabetext += mline[1] + " \n" wbfile.close() return ausgabetext def remorse_en(eingabetext): alphabet = {'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----', 'Ñ': '--.--', 'É': '..-..', 'È': '.-..-', 'À': '.--.-', 'Ü': '..--', 'Ö': '---.', 'Ä': '.-.-', '_': '..--.-', '@': '.--.-.', '?': '..--..', '=': '-...-', ';': '-.-.-.', ':': '---...', '/': '-..-.', '.': '.-.-.-', '-': '-....-', ',': '--..--', '+': '.-.-.', ')': '-.--.-', '(': '-.--.', "'": '.----.', 'SS': '...--..'} ualphabet = {v: k for k, v in alphabet.items()} ualphabet["...--.."] = "ß" eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### RE-Morse EN\n" "Es gibt ja so Leute, die finden es lustig einen Morsecode so aufzuschreiben, daß zwar Wort für Wort " "getrennt wird, aber ansonsten einfach mal die Leerzeichen weggelassen werden. Bei genau solchen " "fiesen Gemeinheiten hilft diese Funktion. Mit Hilfe der englischen Wörterliste en_US-large.txt vom " "Project https://sourceforge.net/projects/wordlist wird überprüft, für welches Wort der eingegebene " "Morsecode stehen könnte.") else: try: wbfile = open("./data/en_US-large.txt", "r", encoding="UTF-8") except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_der eingegebene Morsecode kann für folgendes stehen:_ \n" if eingabetext in ualphabet: ausgabetext += ualphabet[eingabetext] + " \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") mzeile = "" try: for char in zeile: mzeile += alphabet[char.upper()] except KeyError: continue if eingabetext == mzeile: ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def t9_de(eingabetext): eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### T9-DE\n" "Diese Funktion benutzt die deutsche Wörterbuchdatei german.dic vom Project " "https://sourceforge.net/projects/germandict ermittelt diese Funktion alle im Wörterbuch " "enthaltenen Wörter die zu der eingegebenen T9-kodierten Ziffernfolge passen und gibt " "diese aus. \n" "Bsp. 56673462836 liefert das Wort Koordinaten \n" "Da eine Abfrage relativ lange dauert gibt es die Möglichkeit ein spezielles t9-Wörterbuch " "generieren zu lassen, welches ab der nächsten Abfrage dann genutzt wird und wodurch dann nur noch ca. " "15% der Zeit pro Abfrage benötigt wird. Um die Erstellung des t9-de.dic zu starten muß das Wort " "GENERATE (Großschreibung beachten!) ins Eingabefeld eingetragen werden und der Funktionsknopf " "betätigt werden.") else: try: wbfile = open("./data/t9-de.dic", "r", encoding="iso-8859-15") except FileNotFoundError: try: testfile = open("./data/german.dic", "r") testfile.close() if eingabetext == "GENERATE": helper.t9_generate_t9de() return "t9-Wörterbuch wurde erzeugt und wird ab dem nächsten Aufruf der Funktion benutzt." else: ausgabetext = ("_Da das T9-Wörterbuch nicht vorhanden ist, wurde das normale Wörterbuch für die_ " "_Suche benutzt. Das dauert zwar ca. 7x so lange, aber geht auch._ \n" "_Um das spezielle T9-Wörterbuch zu erzeugen bitte das Wort:_ __GENERATE__ _ins_ " "_Eingabefeld eingeben und die Funktion starten._ \n \n") return ausgabetext + helper.t9_germandic(eingabetext) except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_der eingegebene T9-Code kann für folgendes stehen:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") mline = zeile.split(",") if eingabetext == mline[0]: ausgabetext += mline[1] + " \n" wbfile.close() return ausgabetext def t9_en(eingabetext): alphabet = {'A': '2', 'B': '2', 'C': '2', 'D': '3', 'E': '3', 'F': '3', 'G': '4', 'H': '4', 'I': '4', 'J': '5', 'K': '5', 'L': '5', 'M': '6', 'N': '6', 'O': '6', 'P': '7', 'Q': '7', 'R': '7', 'S': '7', 'T': '8', 'U': '8', 'V': '8', 'W': '9', 'X': '9', 'Y': '9', 'Z': '9', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', '0': '0', 'Ñ': '6', 'É': '3', 'È': '3', 'À': '2', 'Ü': '8', 'Ö': '6', 'Ä': '2', '@': '1', '?': '1', '=': '0', ':': '1', '/': '1', '.': '1', '-': '1', ',': '1', '+': '0', ')': '1', '(': '1', 'SS': '7'} eingabetext = eingabetext.rstrip() if eingabetext == "": return ("### T9-EN\n" "Mit Hilfe der englischen Wörterliste en_US-large.txt vom Project " "https://sourceforge.net/projects/wordlist ermittelt diese Funktion alle im Wörterbuch " "enthaltenen Wörter die zu der eingegebenen T9-kodierten Ziffernfolge passen und gibt diese aus. \n" "Bsp. 26673462837 liefert das Wort coordinates") else: try: wbfile = open("./data/en_US-large.txt", "r", encoding="UTF-8") except FileNotFoundError: return "Leider konnte die Wörterbuchdatei nicht geladen werden." else: ausgabetext = "_der eingegebene T9-Code kann für folgendes stehen:_ \n" for zeile in wbfile: zeile = zeile.strip(" \t\n\r") mzeile = "" try: for char in zeile: mzeile += alphabet[char.upper()] except KeyError: continue if eingabetext == mzeile: ausgabetext += zeile + " \n" wbfile.close() return ausgabetext def vigenere(eingabetext, pw): hilfetext = ("### Vigenere-Chiffre\n" "Die Eingabe eines Schlüsselwortes ist hier erforderlich!!! Die Vigenere-Chiffre baut auf dem Prinzip " "der Cesar-Chiffre auf, wobei hier die Verschiebung jedes einzelnen Buchstaben durch die " "Buchstabenwerte eines Schlüsselwortes definiert werden. Da der zu verschlüsselnde Text im " "allgemeinen länger als das Schlüsselwort ist, wird das Schlüsselwort immer wieder wiederholt. " "Ist der Schlüssel mindestens genauso lang wie der Klartext entspricht dies dann dem " "One-Time-Pad-Chiffre. Der eingegebene Text wird hier mit dem eingegebenen Schlüsselwort kodiert und " "dekodiert ausgegeben und zwar sowohl in der Variante, daß Sonderzeichen Schlüsselbuchstaben " "verbrauchen als auch nicht.") bw = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, 'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, 'P': 16, 'Q': 17, 'R': 18, 'S': 19, 'T': 20, 'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26} ubw = {v: k for k, v in bw.items()} if pw is None: return hilfetext pw = pw.strip() text = eingabetext.rstrip() if text == "" or pw == "": return hilfetext else: for b in pw: if b.upper() not in bw: return "Das Passwort darf nur die Buchstaben A-Z / a-z enthalten!" pwl = len(pw) encoded_text = "" encoded_text_s = "" # wenn Leer und Sonderzeichen Schlüsselbuchstaben verbrauchen auslz = 0 # auslasszähler zählt zeichen die im text nicht codiert wurden for i in range(len(text)): if text[i].upper() not in bw: encoded_text += text[i] auslz += 1 encoded_text_s += text[i] else: b1 = bw[text[i].upper()] b2 = bw[pw[(i - auslz) % pwl].upper()] b2s = bw[pw[i % pwl].upper()] ba = (b1 + b2 - 1) % 26 bas = (b1 + b2s - 1) % 26 if ba == 0: ba = 26 if bas == 0: bas = 26 if text[i] == text[i].upper(): encoded_text += ubw[ba] encoded_text_s += ubw[bas] else: encoded_text += ubw[ba].lower() encoded_text_s += ubw[bas].lower() decoded_text = "" decoded_text_s = "" auslz = 0 # auslasszähler zählt zeichen die im text nicht codiert wurden for i in range(len(text)): if text[i].upper() not in bw: decoded_text += text[i] auslz += 1 decoded_text_s += text[i] else: b1 = bw[text[i].upper()] b2 = bw[pw[(i - auslz) % pwl].upper()] b2s = bw[pw[i % pwl].upper()] ba = (b1 - b2 + 1) % 26 bas = (b1 - b2s + 1) % 26 if ba == 0: ba = 26 if bas == 0: bas = 26 if text[i] == text[i].upper(): decoded_text += ubw[ba] decoded_text_s += ubw[bas] else: decoded_text += ubw[ba].lower() decoded_text_s += ubw[bas].lower() ausgabetext = f"_Dekodiert - normal:_ \n{decoded_text} \n \n_Kodiert - normal:_ \n{encoded_text} \n \n" ausgabetext += f"_Dekodiert - Sonderzeichen verbrauchen Schlüsselbuchstaben:_ \n{decoded_text_s} \n \n" ausgabetext += f"_Kodiert - Sonderzeichen verbrauchen Schlüsselbuchstaben:_ \n{encoded_text_s}" return ausgabetext def wolseley(eingabetext, pw): hilfetext = ("### Wolseley-Chiffre\n" "Die Eingabe eines Schlüsselwortes ist hier erforderlich!!! Die Woseley-Chiffre arbeitet mit einem " "Schlüsselwort über welches dann ein Codealphabet/Codequadrat gebildet wird mit welchem dann sowohl " "kodiert als auch dekodiert wird. Angefangen wird dabei mit dem jeweils ersten Vorkommen eines " "Buchstaben im Schlüsselwort und danach folgen die restlichen Buchstaben des Alphabets die nicht im " "Schlüsselwort vorkommen. Da hier nur 25 Zeichen zur Verfügung stehen wird das J mit dem I " "zusammengefasst und als I behandelt und dargestellt. Sonstige Zeichen die nicht im Codealphabet " "vorhanden sind werden unverändert ausgegeben. \n \n" "Codealpahbet mit Schlüsselwort: Teebaum \n" "| | | | | | | | | | | | | | | | | | | | | | | | | |\n" "|-|-|-|-|-|-|-|-|-|-|-|---|-|---|-|-|-|-|-|-|-|-|-|-|-|\n" "|T|E|B|A|U|M|C|D|F|G|H|I/J|K|L |N|O|P|Q|R|S|V|W|X|Y|Z|\n" "|Z|Y|X|W|V|S|R|Q|P|O|N|L |K|I/J|H|G|F|D|C|M|U|A|B|E|T|\n \n" "Bei der Chiffrierung/Dechiffrierung wird im Text nun der erste Buchstabe mit dem letzten getauscht, " "der 2. mit dem Vorletzten, usw. also aus T wird Z und umgekehrt,E<->Y, B<->X, A<->W usw.. nur ein " "K bleibt ein K") abc = "ABCDEFGHIKLMNOPQRSTUVWXYZ" # j wird als i chiffriert if pw is None: return hilfetext text = eingabetext.rstrip() pw = pw.strip() if text == "" or pw == "": return hilfetext else: for b in pw: if b.upper() not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": return "Das Passwort darf nur die Buchstaben A-Z / a-z enthalten!" text = text.upper() pw = pw.upper() if "J" in text: text = text.replace("J", "I") if "J" in pw: pw = pw.replace("J", "I") calpha = "" for b in pw: if b not in calpha: calpha += b for b in abc: if b not in calpha: calpha += b cabc = {calpha[12]: calpha[12]} c1 = calpha[:12] c2 = calpha[13:] c2 = c2[::-1] for i in range(12): cabc[c1[i]] = c2[i] ucabc = {v: k for k, v in cabc.items()} cabc.update(ucabc) atxt = "" for b in text: if b in cabc: atxt += cabc[b] else: atxt += b return atxt def atbash(eingabetext): hilfetext = ("### Atbash-Chiffre\n" "Atbash ist eine einfache Ersetzungschiffre die für das hebräische Alphabet entwickelt wurde, welche " "später auf das lateinische Alphabet übertragen wurde. Dabei wird dem normalen Alphabet ein " "rückwärts gelesenes Alphabet gegenüber gestellt. A wird zu Z, B zu Y usw. Kodierung und Dekodierung " "erfolgt über die selbe Funktion. \n \n" "Codealpahbet: \n" "| | | | | | | | | | | | | | | | | | | | | | | | | | |\n" "|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|\n" "|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|\n" "|Z|Y|X|W|V|U|T|S|R|Q|P|O|N|M|L|K|J|I|H|G|F|E|D|C|B|A|") text = eingabetext.rstrip() if text == "": return hilfetext else: abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" uabc = abc[::-1] cabc = {} for i in range(26): cabc[abc[i]] = uabc[i] atxt = "" for b in text: if b.upper() in cabc: if b == b.upper(): atxt += cabc[b] else: atxt += cabc[b.upper()].lower() else: atxt += b return atxt def monoalphasubstitution(eingabetext, pw): hilfetext = ("### Monoalphabetische Substitutions-Chiffre\n" "Bei der monoalphabetischen Substitution wird jedem Buchstaben des Alphabets der Buchstabe eines " "Schlüsselalphabets zugeordnet: \n" "|Bsp.| |\n" "|----|-|\n" "|Klartextalphabet|ABCDEFGHIJKLMNOPQRSTUVWXYZ|\n" "|Schlüsselalphabet|DSBJFALKNVPOQXYWCEGHIMRTUZ|\n \n" "Spezialformen dieser Chiffre sind Atbash, Cesar, Rot13. Die Funktion hier arbeitet so, daß entweder " "ein komplettes Schlüsselalphabet oder ein Schlüsselwort verwendet werden kann. Bei Verwendung eines " "Schlüsselwortes, wird der Rest des Schlüsselalphabets automatisch aufgefüllt. \n" "Aus dem Schlüsselwort GutenMorgenLiebeSonne wird z. B. dann das Schlüsselalphabet: " "GUTENMORLIBSACDFHJKPQVWXYZ \n" "| | |\n|-|-|\n|Schlüsselwort|GutenMorgenLiebeSonne|\n|Schlüsselalphabet|GUTENMORLIBSACDFHJKPQVWXYZ|") if pw is None: return hilfetext text = eingabetext.rstrip() pw = pw.strip() if text == "" or pw == "": return hilfetext else: abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" for b in pw: if b.upper() not in abc: return "Das Schlüsselwort/Schlüsselalphabet darf nur die Buchstaben A-Z / a-z enthalten!" cabc = "" for b in pw.upper() + abc: if b not in cabc: cabc += b cab = {} for i in range(26): cab[abc[i]] = cabc[i] ucab = {v: k for k, v in cab.items()} encoded_txt = "" for b in text: if b.upper() in cab: if b == b.upper(): encoded_txt += cab[b] else: encoded_txt += cab[b.upper()].lower() else: encoded_txt += b decoded_txt = "" for b in text: if b.upper() in ucab: if b == b.upper(): decoded_txt += ucab[b] else: decoded_txt += ucab[b.upper()].lower() else: decoded_txt += b ausgabetext = f"_Dekodiert:_ \n{decoded_txt} \n \n" ausgabetext += f"_Kodiert:_ \n{encoded_txt} \n \n" if len(pw) < len(abc): ausgabetext += f"Schlüsselalphabet wurde wie folgt aufgefüllt: {cabc}" return ausgabetext def autokey(eingabetext, pw): hilfetext = ("### Autokey-Chiffre\n" "Die Autokey-Chiffre arbeitet nach dem selben Prinzip wie Vignere-Chiffre mit dem Unterschied, dass " "hier am Ende des Schlüsselwortes nicht wieder und wieder das Schlüsselwort angehängt wird, sondern " "der Klartext an das Schlüsselwort angehangen wird. Der eingegebene Text wird hier mit dem " "eingegebenen Schlüsselwort kodiert und dekodiert ausgegeben.") if pw is None: return hilfetext text = eingabetext.rstrip() pw = pw.strip() if text == "" or pw == "": return hilfetext else: bw = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'H': 8, 'I': 9, 'J': 10, 'K': 11, 'L': 12, 'M': 13, 'N': 14, 'O': 15, 'P': 16, 'Q': 17, 'R': 18, 'S': 19, 'T': 20, 'U': 21, 'V': 22, 'W': 23, 'X': 24, 'Y': 25, 'Z': 26} ubw = {v: k for k, v in bw.items()} p_we = "" p_wd = "" for b in pw: if b.upper() not in bw: return "Das Schlüsselwort darf nur die Buchstaben A-Z / a-z enthalten!" else: p_we += b.upper() # Sonderzeichen aus PW entfernen und p_wd += b.upper() if len(p_we) < len(text): for b in text: if b.upper() in bw: p_we += b.upper() encoded_text = "" auslz = 0 # auslasszähler zählt zeichen die im text nicht codiert wurden for i in range(len(text)): if text[i].upper() not in bw: encoded_text += text[i] auslz += 1 else: b1 = bw[text[i].upper()] b2 = bw[p_we[(i - auslz)]] ba = (b1 + b2 - 1) % 26 if ba == 0: ba = 26 if text[i] == text[i].upper(): encoded_text += ubw[ba] else: encoded_text += ubw[ba].lower() decoded_text = "" auslz = 0 for i in range(len(text)): if text[i].upper() not in bw: decoded_text += text[i] auslz += 1 else: b1 = bw[text[i].upper()] b2 = bw[p_wd[(i - auslz)].upper()] ba = (b1 - b2 + 1) % 26 if ba == 0: ba = 26 p_wd += ubw[ba] if text[i] == text[i].upper(): decoded_text += ubw[ba] else: decoded_text += ubw[ba].lower() ausgabetext = f"_Dekodiert:_ \n{decoded_text} \n \n" ausgabetext += f"_Kodiert:_ \n{encoded_text}" return ausgabetext def polybios_encode(eingabetext, pw): hilfetext = ('### Polybios-Chiffre kodieren\n' 'Die 5x5 Polybios-Chiffre kodiert Buchstaben zu zweistelligen Zahlen dazu wird das Schlüsselalphabet ' 'in ein 5x5-Quadrat eingetragen. Die Buchstaben werden dann sozusagen zu ihren entsprechenden ' '"Koordinaten" kodiert. Im unten gezeigten Quadrat wird so aus A 11, aus B 12, aus Q 41, usw. Da in ' 'ein 5x5 Quadrat nur 25 Buchstaben passen wird typischer Weise J und I zusammengefasst, (alternativ ' 'auch U und V), sollen auch Ziffern kodiert werden wird mit einem 6x6-Quadrat gearbeitet, bei ' 'welchem dann für das komplette Alphabet und die Ziffern 0-9 Platz ist. \n' '| |1|2|3|4|5|\n' '|-|-|-|-|-|-|\n' '|1|A|B|C|D|E|\n' '|2|F|G|H|I|K|\n' '|3|L|M|N|O|P|\n' '|4|Q|R|S|T|U|\n' '|5|V|W|X|Y|Z|\n\n' 'Kommt für die Chiffre ein Schlüsselwort zum Einsatz wird das Code-Quadrat so abgeändert das die ' 'Buchstaben des Schlüsselwortes entsprechend ihres ersten Vorkommens Zeile für Zeile in das ' 'Codequadrat eingetragen werden, der Rest wird mit den verbliebenen Buchstaben aufgefüllt. Zur ' 'Information wird für jede Polybios-Variante auch noch einmal der verwendete Klartext und das ' 'verwendete Passwort ausgegeben.') if pw is None: return hilfetext text = eingabetext.rstrip() pw = pw.strip() if text == "": return hilfetext else: qz5 = [11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45, 51, 52, 53, 54, 55] alpha5ij = "ABCDEFGHIKLMNOPQRSTUVWXYZ" # j wird durch i ersetzt alpha5uv = "ABCDEFGHIJKLMNOPQRSTUWXYZ" # v wird durch u ersetzt qz6 = [11, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 31, 32, 33, 34, 35, 36, 41, 42, 43, 44, 45, 46, 51, 52, 53, 54, 55, 56, 61, 62, 63, 64, 65, 66] alpha6 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" text = text.upper() textij = text.replace("J", "I") textuv = text.replace("V", "U") pw = pw.upper() p_wi = pw.replace("J", "I") p_wu = pw.replace("V", "U") passw5ij = "" for i in p_wi: if i in alpha5ij: passw5ij += i passw5uv = "" for i in p_wu: if i in alpha5uv: passw5uv += i passw6 = "" for i in p_wi: if i in alpha6: passw6 += i text5ij = "" for i in textij: if i in alpha5ij or i == " ": text5ij += i text5uv = "" for i in textuv: if i in alpha5uv or i == " ": text5uv += i text6 = "" for i in text: if i in alpha6 or i == " ": text6 += i pw5ij = "" for b in p_wi + alpha5ij: if b in alpha5ij and b not in pw5ij: pw5ij += b pw5uv = "" for b in p_wu + alpha5uv: if b in alpha5uv and b not in pw5uv: pw5uv += b pw6 = "" for b in pw + alpha6: if b in alpha6 and b not in pw6: pw6 += b wb5ij = {" ": " "} for i in range(25): wb5ij[pw5ij[i]] = str(qz5[i]) wb5uv = {" ": " "} for i in range(25): wb5uv[pw5uv[i]] = str(qz5[i]) wb6 = {" ": " "} for i in range(36): wb6[pw6[i]] = str(qz6[i]) ctext5ij = "" for b in text5ij: ctext5ij += wb5ij[b] ctext5uv = "" for b in text5uv: ctext5uv += wb5uv[b] ctext6 = "" for b in text6: ctext6 += wb6[b] ausgabetext = "|Polybios 5x5 (j=i)| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Klartext|{text5ij}|\n" ausgabetext += f"|Schlüsselwort|{passw5ij}|\n" ausgabetext += f"|kodiert|{ctext5ij}\n \n" ausgabetext += "|Polybios 5x5 (v=u)| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Klartext|{text5uv}|\n" ausgabetext += f"|Schlüsselwort|{passw5uv}|\n" ausgabetext += f"|kodiert|{ctext5uv}|\n \n" ausgabetext += "|Polybios 6x6| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Klartext|{text6}|\n" ausgabetext += f"|Schlüsselwort|{passw6}|\n" ausgabetext += f"|kodiert|{ctext6}|\n" return ausgabetext def polybios_decode(eingabetext, pw): hilfetext = ('### Polybios-Chiffre dekodieren\n' 'Die 5x5 Polybios-Chiffre kodiert Buchstaben zu zweistelligen Zahlen dazu wird das Schlüsselalphabet ' 'in ein 5x5-Quadrat eingetragen. Die Buchstaben werden dann sozusagen zu ihren entsprechenden ' '"Koordinaten" kodiert. Im unten gezeigten Quadrat wird so aus A 11, aus B 12, aus Q 41, usw. Da in ' 'ein 5x5 Quadrat nur 25 Buchstaben passen wird typischer Weise J und I zusammengefasst, (alternativ ' 'auch U und V), sollen auch Ziffern kodiert werden wird mit einem 6x6-Quadrat gearbeitet, bei ' 'welchem dann für das komplette Alphabet und die Ziffern 0-9 Platz ist. \n' '| |1|2|3|4|5|\n' '|-|-|-|-|-|-|\n' '|1|A|B|C|D|E|\n' '|2|F|G|H|I|K|\n' '|3|L|M|N|O|P|\n' '|4|Q|R|S|T|U|\n' '|5|V|W|X|Y|Z|\n\n' 'Kommt für die Chiffre ein Schlüsselwort zum Einsatz wird das Code-Quadrat so abgeändert das die ' 'Buchstaben des Schlüsselwortes entsprechend ihres ersten Vorkommens Zeile für Zeile in das ' 'Codequadrat eingetragen werden, der Rest wird mit den verbliebenen Buchstaben aufgefüllt. Zur ' 'Information wird für jede Polybios-Variante auch noch einmal das verwendete Passwort ausgegeben.') if pw is None: return hilfetext text = eingabetext.rstrip() pw = pw.strip() if text == "": return hilfetext else: qz5 = [11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45, 51, 52, 53, 54, 55] alpha5ij = "ABCDEFGHIKLMNOPQRSTUVWXYZ" # j wird durch i ersetzt alpha5uv = "ABCDEFGHIJKLMNOPQRSTUWXYZ" # v wird durch u ersetzt qz6 = [11, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 26, 31, 32, 33, 34, 35, 36, 41, 42, 43, 44, 45, 46, 51, 52, 53, 54, 55, 56, 61, 62, 63, 64, 65, 66] alpha6 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" pw = pw.upper() p_wi = pw.replace("J", "I") p_wu = pw.replace("V", "U") passw5ij = "" for i in p_wi: if i in alpha5ij: passw5ij += i passw5uv = "" for i in p_wu: if i in alpha5uv: passw5uv += i passw6 = "" for i in p_wi: if i in alpha6: passw6 += i pw5ij = "" for b in p_wi + alpha5ij: if b in alpha5ij and b not in pw5ij: pw5ij += b pw5uv = "" for b in p_wu + alpha5uv: if b in alpha5uv and b not in pw5uv: pw5uv += b pw6 = "" for b in pw + alpha6: if b in alpha6 and b not in pw6: pw6 += b wb5ij = {" ": " "} for i in range(25): wb5ij[str(qz5[i])] = pw5ij[i] wb5uv = {" ": " "} for i in range(25): wb5uv[str(qz5[i])] = pw5uv[i] wb6 = {" ": " "} for i in range(36): wb6[str(qz6[i])] = pw6[i] text = text.split() ctext5ij = "" ctext5uv = "" ctext6 = "" for wort in text: for i in range(0, len(wort), 2): cc = wort[i:i + 2] if cc in wb5ij: ctext5ij += wb5ij[cc] if cc in wb5uv: ctext5uv += wb5uv[cc] if cc in wb6: ctext6 += wb6[cc] ctext5ij += " " ctext5uv += " " ctext6 += " " ausgabetext = "|Polybios 5x5 (j=i)| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Schlüsselwort|{passw5ij}|\n" ausgabetext += f"|dekodiert|{ctext5ij}|\n \n" ausgabetext += "|Polybios 5x5 (v=u)| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Schlüsselwort|{passw5uv}|\n" ausgabetext += f"|dekodiert|{ctext5uv}|\n \n" ausgabetext += "|Polybios 6x6| |\n" ausgabetext += "|-|-|\n" ausgabetext += f"|Schlüsselwort|{passw6}|\n" ausgabetext += f"|dekodiert|{ctext6}|\n" return ausgabetext ''' def klopfcode_encode(): hilfetext = """HILFE: [Klopfcode kodieren] Der Klopfcode ist im Prinzip eine Polybios Chiffre mit einem festen Schlüsselquadrat bei welchem nicht I und J sondern C und K zusammengefasst werden. siehe hier: 1 2 3 4 5 1 A B C D E 2 F G H I J 3 L M N O P 4 Q R S T U 5 V W X Y Z """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: qz5 = [11, 12, 13, 14, 15, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45, 51, 52, 53, 54, 55] alpha = "ABCDEFGHIJLMNOPQRSTUVWXYZ" # k wird durch c ersetzt text = text.upper() text = text.replace("K", "C") text5 = "" for i in text: if i in alpha or i == " ": text5 += i wb5 = {" ": " "} for i in range(25): wb5[alpha[i]] = str(qz5[i]) ctext = "" for b in text5: ctext += wb5[b] Ausgabe.insert(1.0, ctext + "\n") Ausgabe.insert(1.0, "Klartext: " + text5 + "\n", "gr") def klopfcode_decode(): hilfetext = """HILFE: [Klopfcode dekodieren] Der Klopfcode ist im Prinzip eine Polybios Chiffre mit einem festen Schlüsselquadrat bei welchem nicht I und J sondern C und K zusammengefasst werden. siehe hier: 1 2 3 4 5 1 A B C D E 2 F G H I J 3 L M N O P 4 Q R S T U 5 V W X Y Z """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: qz5 = [11, 12, 14, 15, 21, 22, 23, 24, 25, 31, 32, 33, 34, 35, 41, 42, 43, 44, 45, 51, 52, 53, 54, 55] alpha = "ABDEFGHIJLMNOPQRSTUVWXYZ" # k wird durch c ersetzt wb = {" ": " ", "13": "[C/K]"} for i in range(24): wb[str(qz5[i])] = alpha[i] text = text.split() ctext = "" for wort in text: for i in range(0, len(wort), 2): cc = wort[i:i + 2] if cc in wb: ctext += wb[cc] ctext += " " Ausgabe.insert(1.0, ctext + "\n") Ausgabe.insert(1.0, "Klopfcode dekodiert:\n", "bu") def maptiles_kachelkoordinaten(): hilfetext = """HILFE: [Maptiles / Kachelkoordinaten] Bei vielen Online-Kartendiensten wie Openstreetmap oder Google-Maps erfolgt die Kartendarstellung über vorberechnete "Kachel"-Grafikdateien, welche ein Adressierungssystem benötigen damit je nach Koordinate und Zoomstufe auch der richtige Kartenausschnitt dargestellt und klar ist welche Kacheln daneben darzustellen ist wird.Bei OSM ist eine solche Kachel eine PNG-Grafik mit 256x256 Pixeln und je nach Zoomstufe ist eine unterschiedliche Anzahl solcher Kacheln/Tiles notwendig um die ganze Welt abzubilden. Da je Zoomstufe sich die Anzahl der benötigten Kacheln vervierfacht ist bei den meisten Diensten bei Zoomlevel 18 Schluß, OSM geht bis Zoomlevel 19. Um die einzelnen Kacheln beim tilemap-Server abzufragen braucht man die Zoomstufe, einen X und einen Y-Wert wobei dies alles ganzzahlige Werte sind. Aufgerufen von den Servern werden die Kacheln dann nach dem Muster: "http://servername/Zoom/X/Y.png" Den Fernsehturm mit Zoomstufe 18 findet man z.B. bei Openstreetmap hier:https://tile.openstreetmap.org/18/140836/85970.png Die Funktion arbeitet hier auf die Art und Weise, daß man 2 durch ein Freizeichen getrennte Zahlen eingibt. Handelt es sich bei den angegebenen Zahlen um "Kommazahlen" welche allerdings mit Punkt anzugeben sind (Bsp: 52.520803 13.4088653 ) geht die Funktion davon aus, daß es sich um Koordinaten in Dezimalgrad handelt und sofern es gültige Koordinaten sind erfolgt eine Ausgabe der X und Y Werte für die Zoomstufen und 1-30. (Positive Zahlen stehen für Nord und Ost, negative für Süd und West) Handelt es sich bei den beiden Zahlen um Ganzzahlen wird davon ausgegangen, daß es sich um X und Y Werte handelt und es werde für alle Zoomstufen von 1-30 Koordinaten in Dezimalminuten und Dezimalgrad ausgegeben, sofern dies sinnvolle Koordinaten ergibt. """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: text = text.split() if "." in text[0] and len(text) == 2: for zoom in range(30, 0, -1): try: la = float(text[0]) lo = float(text[1]) if not la < -180 and not la > 180 and not lo < -180 and not lo > 180: x, y = helper.dec_to_maptiles(la, lo, zoom) Ausgabe.insert(1.0, "Zoom:{:>2} X:{:<10} Y:{}\n".format(zoom, x, y)) except ValueError: pass Ausgabe.insert(1.0, "DEC -> Maptiles\n", "bu") elif len(text) == 2: for zoom in range(30, 0, -1): try: la, lo = helper.maptiles_to_dec(int(text[0]), int(text[1]), zoom) if not la < -180 and not la > 180 and not lo < -180 and not lo > 180: Ausgabe.insert(1.0, "Zoom:{:>2} DEG: {:<23} DEC: {} {}\n".format(zoom, helper.dec_to_deg(la, lo), round(la, 5), round(lo, 5))) except ValueError: pass Ausgabe.insert(1.0, "Maptiles->DEG,DEC\n", "bu") else: Ausgabe.insert(1.0, "Zahlen konnten nicht ermittelt werden!\n", "re") def quadtreekoordinaten(): hilfetext = """HILFE: [Quadtree-/Quadkeykoordinaten] Diese Koordinatenkodierung spielt in der alltäglichen Praxis eigentlich kaum noch ein Rolle, außer scheinbar bei bing-maps und beim Geocaching. Sie dient ähnlich wie das Maptiles-System dazu Grafikdateien für unterschiedliche Zoomstufen einer Karte zu adressieren. Die Länge der Zahl entspricht hier zugleich auch dem Detailgrad bzw. der Zoomstufe. Es finden nur die Zahlen 0,1,2 und 3 Verwendung, wobei die 0 den Nordwestlichen Quadranten, 1 den Nordöstlichen, 2 SW und 3 SO. Ein kleines Beispiel: 230 würde bedeuten es geht im südwestlichen Quadranten (2) um den südöstlichen Quadranten(3) und in diesem wiederum um den nordwestlichen Quadranten. Je länger also diese Zahlenreihe aus 0,1,2 und 3 wird um so genauer wird ein bestimmter Ort angegeben. Weitere Infos gibt es unter folgendem Link zu finden: https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system Die Funktion ermittelt aus einer Quadtreekoordinate die Maptileskoordinaten und die WGS-Koordinaten. """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: tilex = 0 tiley = 0 quadkey = text fehler = 0 zoom = len(quadkey) for i in range(zoom, 0, -1): mask = 1 << (i - 1) if quadkey[zoom - i] == "0": continue if quadkey[zoom - i] == "1": tilex |= mask continue if quadkey[zoom - i] == "2": tiley |= mask continue if quadkey[zoom - i] == "3": tilex |= mask tiley |= mask continue else: fehler += 1 la, lo = maptiles_to_dec(tilex, tiley, zoom) if fehler == 0: Ausgabe.insert(1.0, "DEG: {}\n".format(dec_to_deg(la, lo))) Ausgabe.insert(1.0, "DEC: {} {}\n".format(round(la, 5), round(lo, 5))) Ausgabe.insert(1.0, "Maptiles: X:{} Y:{} Zoom:{}\n".format(tilex, tiley, zoom)) else: Ausgabe.insert(1.0, "Es konnte keine gültige Quadtree-Koordinate erkannt werden.\n" "(eine Zahl die nur die Ziffern 0,1,2,3 enthält)\n") def chronogramm(): hilfetext = """HILFE: [Chronogramm/ römische Ziffern zählen] Ein Chronogramm (oder Eteostichon) ist ein Satzteil, ein Satz, ein Sinnspruch oder eine Inschrift, meist ein Vers in lateinischer Sprache, in dem diejenigen Buchstaben, die auch als römische Zahlzeichen gelesen werden können (I, V, X, L, C, D, M), in ihrer Summe die Jahreszahl des Ereignisses angeben, auf das sich der Text bezieht. Entscheidend ist allein die Summe der Zahlenwertbuchstaben, die sonst bei römischen Zahlen übliche Subtraktion kleinerer Zahlenwerte von folgenden größeren erfolgt nicht. Die Zahlbuchstaben sind meist hervorgehoben, etwa durch Großschreibung oder Verdickung der Buchstaben bzw. durch farbliche Abhebung mittels Rötung oder Vergoldung. Eine Besonderheit bilden Krypto(chrono)gramme, bei denen die Zahlbuchstaben nicht gekennzeichnet sind und "verborgen" bleiben. Bei der einfachen Analyse werden hier die Buchstaben I(1),V(5),X(10),L(50), C(100), D(500), M(1000) berücksichtigt und addiert, bei der erweiterten Analyse wird zunächst einmal berücksichtigt, daß im Lateinischen Alphabet der Buchstabe J als I und der Buchstabe U als V geschrieben wird. Außerdem erfolgt wird in der extremen Variante auch noch W=10(V+V) und Y=2(I+I) berücksichtigt. Desweiteren wird auch für jeden relevanten Buchstaben einzeln noch einmal die Anzahl und Summe angezeigt. Eine Unterscheidung zwischen Klein- und Großschreibung findet nicht statt. """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: text = text.upper() i, v, x, ll, c, d, m, y, w, u, j = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 for r_chr in text: if r_chr == "I": i += 1 if r_chr == "V": v += 1 if r_chr == "X": x += 1 if r_chr == "L": ll += 1 if r_chr == "C": c += 1 if r_chr == "D": d += 1 if r_chr == "M": m += 1 if r_chr == "U": u += 1 if r_chr == "J": j += 1 if r_chr == "Y": y += 1 if r_chr == "W": w += 1 sum_einfach = i + (v * 5) + (x * 10) + (ll * 50) + (c * 100) + (d * 500) + (m * 1000) sum_erweitert = sum_einfach + (u * 5) + j sum_extrem = sum_erweitert + (y * 2) + (w * 10) Ausgabe.insert(1.0, "Summe extrem(inkl.J,U,Y,W): {}\n".format(sum_extrem)) Ausgabe.insert(1.0, "Summe erweitert(inkl. I,U): {}\n".format(sum_erweitert)) Ausgabe.insert(1.0, "Summe einfach(I,V,X,L,C,D,M): {}\n".format(sum_einfach)) Ausgabe.insert(1.0, "W(V+V=10):{:5}x \tSumme W: {}\n".format(w, w * 10), "gr") Ausgabe.insert(1.0, " Y(I+I=2):{:5}x \tSumme Y: {}\n".format(y, y * 2), "gr") Ausgabe.insert(1.0, " U(V=5):{:5}x \tSumme U: {}\n".format(u, u * 5), "gr") Ausgabe.insert(1.0, " J(I=1):{:5}x \tSumme U: {}\n".format(j, j), "gr") Ausgabe.insert(1.0, " M(1000):{:5}x \tSumme M: {}\n".format(m, m * 1000), "gr") Ausgabe.insert(1.0, " D(500):{:5}x \tSumme D: {}\n".format(d, d * 500), "gr") Ausgabe.insert(1.0, " C(100):{:5}x \tSumme C: {}\n".format(c, c * 100), "gr") Ausgabe.insert(1.0, " L(50):{:5}x \tSumme L: {}\n".format(ll, ll * 50), "gr") Ausgabe.insert(1.0, " X(10):{:5}x \tSumme X: {}\n".format(x, x * 10), "gr") Ausgabe.insert(1.0, " V(5):{:5}x \tSumme V: {}\n".format(v, v * 5), "gr") Ausgabe.insert(1.0, " I(1):{:5}x \tSumme I: {}\n".format(i, i), "gr") def adfgx_kodieren(): hilfetext = """HILFE: [ADFGX kodieren] Die ADFGX-Chiffre arbeitet mit zwei Passwörtern, wobei jedes für je einen Kodierungsschritt verwendet wird. Das erste wird benutzt um eine Variation der Polybios-Kodierung mit einem 5x5 Quadrat und J=I durchzuführen bei welcher die Zahlen 1-5 durch die Buchstaben ADFGX ersetzt werden. Mit dem Text "Ein Beispiel",dem Passwort "PASSWORT" und einem mit A->Z aufgefülltem Schlüsselquadrat ergibt der erste Schritt z.B. die Zeichenfolge: "FA FX GG DF FA FX AF AA FX FA GD". Nun kommt das zweite Passwort zum Einsatz als Beispiel hier:"Tester". Zunächst einmal wird die Zeichenfolge 5 1 4 6 2 3 in der Breite des Passwort Zeilenweise darunter geschrieben, T E S T E R nun werden diese Spalten dem Passwort entsprechend F A F X G G alphabetisch sortiert und dann von oben nach unten abgelesen. D F F A F X Im Beispiel fängt es also mit der Spalte 1 dem E an dann das A F A A F X zweite E, dann R usw. was dann als kodierten Text, welcher F A G D typischer Weise in 5er-Blöcken ausgegeben wird folgendes ergibt: AFFAG FFGXX FFAGF DAFXA AD ergibt. Die beiden Varianten, welche ausgegeben werden, unterscheiden sich nur darin, wie das Schlüsselquadrat im ersten Kodierungsschritt aufgefüllt wird. Entweder in alphabetischer Reihenfolge A->Z oder umgekehrt Z->A. """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() pw = PW_Eingabe.get() pw = pw.strip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: rn = ["AA", "AD", "AF", "AG", "AX", "DA", "DD", "DF", "DG", "DX", "FA", "FD", "FF", "FG", "FX", "GA", "GD", "GF", "GG", "GX", "XA", "XD", "XF", "XG", "XX"] alpha_az = "ABCDEFGHIKLMNOPQRSTUVWXYZ" # j wird durch i ersetzt alpha_za = "ZYXWVUTSRQPONMLKIHGFEDCBA" text = text.upper() text = text.replace("J", "I") pw = pw.upper() pw = pw.replace("J", "I") pw = pw.split(",") if len(pw) != 2: Ausgabe.insert(1.0, "Es es werden genau zwei durch Komma getrennte Passwörter benötigt!\n", "re") return pw[0] = pw[0].strip() pw[1] = pw[1].strip() pw1az = "" for b in pw[0] + alpha_az: if b in alpha_az and b not in pw1az: pw1az += b pw1za = "" for b in pw[0] + alpha_za: if b in alpha_za and b not in pw1za: pw1za += b pw2 = "" for i in pw[1]: if i in alpha_az: pw2 += i klartext = "" for i in text: if i in alpha_az: klartext += i w_baz = {} for i in range(25): w_baz[pw1az[i]] = rn[i] w_bza = {} for i in range(25): w_bza[pw1za[i]] = rn[i] ctext1az = "" for b in klartext: ctext1az += w_baz[b] print(ctext1az) ctext1za = "" for b in klartext: ctext1za += w_bza[b] ctext2az = [] for i in range(len(pw2)): ctext2az.append([pw2[i] + str(i + 10)]) for i in range(len(ctext1az)): ctext2az[i % len(pw2)].append(ctext1az[i]) ctext2az.sort() ausgabe_az = "" z = 1 for i in ctext2az: for j in range(len(i) - 1): if z == 5: ausgabe_az += i[j + 1] + " " z = 1 else: ausgabe_az += i[j + 1] z += 1 ctext2za = [] for i in range(len(pw2)): ctext2za.append([pw2[i] + str(i + 10)]) for i in range(len(ctext1za)): ctext2za[i % len(pw2)].append(ctext1za[i]) ctext2za.sort() ausgabe_za = "" z = 1 for i in ctext2za: for j in range(len(i) - 1): if z == 5: ausgabe_za += i[j + 1] + " " z = 1 else: ausgabe_za += i[j + 1] z += 1 Ausgabe.insert(1.0, ausgabe_za + "\n") Ausgabe.insert(1.0, "kodiert mit Variante Z-A:\n") Ausgabe.insert(1.0, ausgabe_az + "\n") Ausgabe.insert(1.0, "kodiert mit Variante A-Z:\n") Ausgabe.insert(1.0, "Passwort 2: {}\n".format(pw2), "gr") Ausgabe.insert(1.0, "Passwort 1: {}\n".format(pw[0]), "gr") def adfgx_dekodieren(): hilfetext = """HILFE: [ADFGX dekodieren] Die ADFGX-Chiffre arbeitet mit zwei Passwörtern, wobei jedes für je einen Kodierungsschritt verwendet wird. Das erste wird benutzt um eine Variation der Polybios-Kodierung mit einem 5x5 Quadrat und J=I durchzuführen bei welcher die Zahlen 1-5 durch die Buchstaben ADFGX ersetzt werden. Mit dem Text "Ein Beispiel",dem Passwort "PASSWORT" und einem mit A->Z aufgefülltem Schlüsselquadrat ergibt der erste Schritt z.B. die Zeichenfolge: "FA FX GG DF FA FX AF AA FX FA GD". Nun kommt das zweite Passwort zum Einsatz als Beispiel hier:"Tester". Zunächst einmal wird die Zeichenfolge 5 1 4 6 2 3 in der Breite des Passwort Zeilenweise darunter geschrieben, T E S T E R nun werden diese Spalten dem Passwort entsprechend F A F X G G alphabetisch sortiert und dann von oben nach unten abgelesen. D F F A F X Im Beispiel fängt es also mit der Spalte 1 dem E an dann das A F A A F X zweite E, dann R usw. was dann als kodierten Text, welcher F A G D typischer Weise in 5er-Blöcken ausgegeben wird folgendes ergibt: AFFAG FFGXX FFAGF DAFXA AD ergibt. Die beiden Varianten, welche ausgegeben werden, unterscheiden sich nur darin, wie das Schlüsselquadrat im ersten Kodierungsschritt aufgefüllt wird. Entweder in alphabetischer Reihenfolge A->Z oder umgekehrt Z->A. """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() pw = PW_Eingabe.get() pw = pw.strip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: rn = ["AA", "AD", "AF", "AG", "AX", "DA", "DD", "DF", "DG", "DX", "FA", "FD", "FF", "FG", "FX", "GA", "GD", "GF", "GG", "GX", "XA", "XD", "XF", "XG", "XX"] alpha_az = "ABCDEFGHIKLMNOPQRSTUVWXYZ" # j wird durch i ersetzt alpha_za = "ZYXWVUTSRQPONMLKIHGFEDCBA" text = text.upper() text = text.replace("J", "I") pw = pw.upper() pw = pw.replace("J", "I") pw = pw.split(",") if len(pw) != 2: Ausgabe.insert(1.0, "Es es werden genau zwei durch Komma getrennte Passwörter benötigt!\n", "re") return pw[0] = pw[0].strip() pw[1] = pw[1].strip() pw1az = "" for b in pw[0] + alpha_az: if b in alpha_az and b not in pw1az: pw1az += b pw1za = "" for b in pw[0] + alpha_za: if b in alpha_za and b not in pw1za: pw1za += b pw2 = "" for i in pw[1]: if i in alpha_az: pw2 += i ctext = "" for i in text: if i in alpha_az: ctext += i w_baz = {} for i in range(25): w_baz[rn[i]] = pw1az[i] w_bza = {} for i in range(25): w_bza[rn[i]] = pw1za[i] ret = ['_'] * len(ctext) lt, lp = len(ctext), len(pw2) t1 = [(pw2[i], i) for i in range(len(pw2))] ind = [q[1] for q in sorted(t1)] upto = 0 for i in range(len(pw2)): tic = int(lt / lp) if ind[i] < lt % lp: tic += 1 ret[ind[i]::lp] = ctext[upto:upto + tic] upto += tic ctext = ''.join(ret) klartext_az = "" for i in range(0, len(ctext), 2): bi = ctext[i:i + 2] if bi in w_baz: klartext_az += w_baz[bi] klartext_za = "" for i in range(0, len(ctext), 2): bi = ctext[i:i + 2] if bi in w_bza: klartext_za += w_bza[bi] Ausgabe.insert(1.0, klartext_za + "\n") Ausgabe.insert(1.0, "dekodiert mit Variante Z-A:\n") Ausgabe.insert(1.0, klartext_az + "\n") Ausgabe.insert(1.0, "dekodiert mit Variante A-Z:\n") Ausgabe.insert(1.0, "Passwort 2: {}\n".format(pw2), "gr") Ausgabe.insert(1.0, "Passwort 1: {}\n".format(pw[0]), "gr") def adfgvx_kodieren(): hilfetext = """HILFE: [ADFGVX kodieren] Die ADFGVX-Chiffre erweitert das 5x5-Schlüsselquadrat der ADFGX-Chiffre ersten Kodierungsschritt auf 6x6 so, daß das komplette Alphabet und die Zahlen 0-9 verwendet werden können. Die beiden ausgegebenen Varianten unterscheiden sich in der Variante wie das Schlüsselquadrat aufgefüllt wird (A->Z + 0->9 oder 9->0 + Z->A). """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() pw = PW_Eingabe.get() pw = pw.strip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: rn = ["AA", "AD", "AF", "AG", "AV", "AX", "DA", "DD", "DF", "DG", "DV", "DX", "FA", "FD", "FF", "FG", "FV", "FX", "GA", "GD", "GF", "GG", "GV", "GX", "VA", "VD", "VF", "VG", "VV", "VX", "XA", "XD", "XF", "XG", "XV", "XX"] alpha_az09 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" alpha_90za = "9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA" text = text.upper() pw = pw.upper() pw = pw.split(",") if len(pw) != 2: Ausgabe.insert(1.0, "Es es werden genau zwei durch Komma getrennte Passwörter benötigt!\n", "re") return pw[0] = pw[0].strip() pw[1] = pw[1].strip() pw1az09 = "" for b in pw[0] + alpha_az09: if b in alpha_az09 and b not in pw1az09: pw1az09 += b pw190za = "" for b in pw[0] + alpha_90za: if b in alpha_90za and b not in pw190za: pw190za += b pw2 = "" for i in pw[1]: if i in alpha_az09: pw2 += i klartext = "" for i in text: if i in alpha_az09: klartext += i w_baz09 = {} for i in range(36): w_baz09[pw1az09[i]] = rn[i] wb90za = {} for i in range(36): wb90za[pw190za[i]] = rn[i] ctext1az09 = "" for b in klartext: ctext1az09 += w_baz09[b] ctext190za = "" for b in klartext: ctext190za += wb90za[b] ctext2az09 = [] for i in range(len(pw2)): ctext2az09.append([pw2[i] + str(i + 10)]) for i in range(len(ctext1az09)): ctext2az09[i % len(pw2)].append(ctext1az09[i]) ctext2az09.sort() ausgabe_az09 = "" z = 1 for i in ctext2az09: for j in range(len(i) - 1): if z == 5: ausgabe_az09 += i[j + 1] + " " z = 1 else: ausgabe_az09 += i[j + 1] z += 1 ctext290za = [] for i in range(len(pw2)): ctext290za.append([pw2[i] + str(i + 10)]) for i in range(len(ctext190za)): ctext290za[i % len(pw2)].append(ctext190za[i]) ctext290za.sort() ausgabe_90za = "" z = 1 for i in ctext290za: for j in range(len(i) - 1): if z == 5: ausgabe_90za += i[j + 1] + " " z = 1 else: ausgabe_90za += i[j + 1] z += 1 Ausgabe.insert(1.0, ausgabe_90za + "\n") Ausgabe.insert(1.0, "kodiert mit Variante 9-0,Z-A:\n") Ausgabe.insert(1.0, ausgabe_az09 + "\n") Ausgabe.insert(1.0, "kodiert mit Variante A-Z,0-9:\n") Ausgabe.insert(1.0, "Passwort 2: {}\n".format(pw2), "gr") Ausgabe.insert(1.0, "Passwort 1: {}\n".format(pw[0]), "gr") def adfgvx_dekodieren(): hilfetext = """HILFE: [ADFGVX dekodieren] Die ADFGVX-Chiffre erweitert das 5x5-Schlüsselquadrat der ADFGX-Chiffre ersten Kodierungsschritt auf 6x6 so, daß das komplette Alphabet und die Zahlen 0-9 verwendet werden können. Die beiden ausgegebenen Varianten unterscheiden sich in der Variante wie das Schlüsselquadrat aufgefüllt wird (A->Z + 0->9 oder 9->0 + Z->A). """ eingabetext = Eingabe.get(1.0, END) text = eingabetext.rstrip() pw = PW_Eingabe.get() pw = pw.strip() if text == "": Ausgabe.insert(1.0, hilfetext + "\n") else: rn = ["AA", "AD", "AF", "AG", "AV", "AX", "DA", "DD", "DF", "DG", "DV", "DX", "FA", "FD", "FF", "FG", "FV", "FX", "GA", "GD", "GF", "GG", "GV", "GX", "VA", "VD", "VF", "VG", "VV", "VX", "XA", "XD", "XF", "XG", "XV", "XX"] alpha_az09 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" alpha_90za = "9876543210ZYXWVUTSRQPONMLKJIHGFEDCBA" text = text.upper() pw = pw.upper() pw = pw.split(",") if len(pw) != 2: Ausgabe.insert(1.0, "Es es werden genau zwei durch Komma getrennte Passwörter benötigt!\n", "re") return pw[0] = pw[0].strip() pw[1] = pw[1].strip() pw1az09 = "" for b in pw[0] + alpha_az09: if b in alpha_az09 and b not in pw1az09: pw1az09 += b pw190za = "" for b in pw[0] + alpha_90za: if b in alpha_90za and b not in pw190za: pw190za += b pw2 = "" for i in pw[1]: if i in alpha_az09: pw2 += i ctext = "" for i in text: if i in alpha_az09: ctext += i w_baz09 = {} for i in range(36): w_baz09[rn[i]] = pw1az09[i] wb90za = {} for i in range(36): wb90za[rn[i]] = pw190za[i] ret = ['_'] * len(ctext) lt, lp = len(ctext), len(pw2) t1 = [(pw2[i], i) for i in range(len(pw2))] ind = [q[1] for q in sorted(t1)] upto = 0 for i in range(len(pw2)): tic = int(lt / lp) if ind[i] < lt % lp: tic += 1 ret[ind[i]::lp] = ctext[upto:upto + tic] upto += tic ctext = ''.join(ret) klartext_az09 = "" for i in range(0, len(ctext), 2): bi = ctext[i:i + 2] if bi in w_baz09: klartext_az09 += w_baz09[bi] klartext_90za = "" for i in range(0, len(ctext), 2): bi = ctext[i:i + 2] if bi in wb90za: klartext_90za += wb90za[bi] Ausgabe.insert(1.0, klartext_90za + "\n") Ausgabe.insert(1.0, "dekodiert mit Variante 0-0,Z-A:\n") Ausgabe.insert(1.0, klartext_az09 + "\n") Ausgabe.insert(1.0, "dekodiert mit Variante A-Z,0-9:\n") Ausgabe.insert(1.0, "Passwort 2: {}\n".format(pw2), "gr") Ausgabe.insert(1.0, "Passwort 1: {}\n".format(pw[0]), "gr") def zahlen_roemisch_arabisch_umwandeln(): hilfetext = """HILFE: [Römische in Arabische Zahlen umwandeln und umgekehrt] Es werden römische Zahlen in arabische umgewandelt und umgekehrt, die Funktion arbeitet dabei bei der Umwandlung von arabisch zu römisch mit Werten bis maximal 500000. Es werden folgende Zeichen verwendet: I=1, V=5, X=10, L=50, C=100, D=500, M=1000, \u2181=5000, \u2182=10000, \u2187=50000, \u2188=100000 Etwas Vorsicht sollte bei einer Umwandlung von römischen in arabische Zahlen geboten sein, wenn mit untypischen Schreibweisen gearbeitet wird bei welchen mehr als ein Zeichen von dem nachfolgenden Zeichen abgezogen werden soll. Die eigentlich inkorrekte Schreibweise IIX für die Zahl 8 wird hier die Zahl 10 als Ergebnis haben (+1-1+10), dafür wird aber allerdings die ebenfalls falsche Schreibweise IM genauso als 999 wie die korrekte Schreibweise CMXCIX erkannt. """ rza = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000, '\u2181': 5000, '\u2182': 10000, '\u2187': 50000, '\u2188': 100000} azr = [(100000, '\u2188'), (90000, '\u2182\u2188'), (50000, '\u2187'), (40000, '\u2182\u2187'), (10000, '\u2182'), (9000, 'M\u2182'), (5000, '\u2181'), (4000, 'M\u2181'), (1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')] eingabetext = Eingabe.get(1.0, END) rz = eingabetext.rstrip() if rz == "": Ausgabe.insert(1.0, hilfetext + "\n") else: rz = rz.upper() try: az = 0 for i in range(len(rz)): if i == len(rz) - 1: az += rza[rz[i]] Ausgabe.insert(1.0, "{} = {}\n".format(rz, az)) else: if rza[rz[i]] < rza[rz[i + 1]]: az -= rza[rz[i]] else: az += rza[rz[i]] except KeyError: try: zahl = int(rz) if zahl > 500000: Ausgabe.insert(1.0, "arabische Zahlen größer als 500000 mag ich nicht in römische Zahlen!\n", "re") return rom = "" for az, romz in azr: count = zahl // az zahl -= az * count rom += romz * count Ausgabe.insert(1.0, "{} = {}\n".format(rz, rom)) except ValueError: Ausgabe.insert(1.0, "Es konnte keine römische oder arabische Zahl erkannt werden!\n", "re") def url_decode(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.rstrip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [URL-decode] Nachdem Groundspeak nun inzwischen sämtliche Bilddateien über einen Proxy umleitet bevor sie im Listing erscheinen wird es manchmal schwer die ursprüngliche URL und/oder den Dateinamen des Bildes noch lesen zu können. Die URL hat dort nun jeweils folgendes Muster: https://imgproxy.geocaching.com/......?url=..... wobei nach dem ?url= dann die ursprüngliche Bild-URL folgt, allerdings wird dabei dann aus http:// folgendes http%3A%2F%2F und um genau dieses wieder normal lesbar zu machen dient diese Funktion\n\n""") else: atxt = urllib_parse_unquote(eingabetext) Ausgabe.insert(1.0, atxt + "\n") Ausgabe.insert(1.0, "dekodierte URL:\n", "bu") def reversewig(): seperator = ("|,", "_", "/", ";", ",") eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.rstrip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [Reverse Wherigo zu Koordinaten] Mit dem Reverse Wherigo hat -Waldmeister- eigentlich eine coole Sache erfunden. Man hat anfangs keine Koordinaten sondern nur 3 Zahlen, welche man nach Start des Wherigo-Cartridges eingibt und dann erfährt man wie weit der Cache entfernt ist. Nun kann man immer wieder von unterschiedlichen Positionen aus diese Entfernungsfragen durchführen und sich damit dem Cache nähern. Je weniger Abfragen man braucht umso besser. Leider gibt es inzwischen genügend Tools die genau wie diese Funktion hier aus den 3 Zahlen direkt die Finalkoordinaten ermitteln können. Leider??? Ja leider denn das führt auch dazu, das es inzwischen so extrem viele dieser Reverse-Wherigos gibt wo sich die Owner anscheinend auch denken "Die spielt doch sowieso keiner mehr normal..." anders kann ich mir ganze Trails mit Reverse-Wherigos nicht erklären. Um die Funktion zu nutzen braucht man nur die 3 Zahlen durch ein entsprechendes Trennzeichen: | , _ / ; , oder Leerzeichen eingeben und auf den Knopp klicken und bekommt Koordinaten. """ + "\n\n") else: se = "" for s in seperator: if s in eingabetext: se = s if se == "" and " " in eingabetext: se = " " if se == "": Ausgabe.insert(1.0, "Keine gültiges Trennzeichen (, ; / _ | oder Leerzeichen) erkannt!\n", "re") else: txt = eingabetext.split(se) if len(txt) == 3: error = 0 for z in txt: try: int(z) except ValueError: Ausgabe.insert(1.0, "Bitte die Eingabezahlen überprüfen\n", "re") error += 1 if error == 0: final = rwig_to_coords(txt[0], txt[1], txt[2]) Ausgabe.insert(1.0, "DEG: " + dec_to_deg(final[0], final[1]) + "\n") Ausgabe.insert(1.0, "DEC: " + str(final[0]) + " " + str(final[1]) + "\n") Ausgabe.insert(1.0, "WIG: " + txt[0] + ", " + txt[1] + ", " + txt[2] + "\n") else: Ausgabe.insert(1.0, "Es wurden nicht 3 Zahlen erkannt.\n", "re") def base64_ascii(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.rstrip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [Base64 <-> ASCII] Base64 ist ein Kodierungsverfahren, welches dazu verwendet wird um beliebige Binärdaten nur Hilfe einer Zeichenkette aus A-Z, a-z, 0-9, +, / sowie am Ende = übertragen zu können. Ein Einsatzzweck dafür ist z.B. wenn bei EMails Dateianhänge verwendet werden, dort werden nahezu alle Dateiformate base64-kodiert übertragen. Auch bei dem einem oder anderen Mystery sind mir solche kodierten Zeichenketten schon begegnet. Wenn am Ende einer Zeichenkette ein oder zwei "="-Zeichen stehen ist die Wahrscheinlichkeit recht groß, das hier base64 verwendet wurde. Das "="-Zeichen dient hier nämlich als "Lückenfüller" am Ende. Die Funktion hier versucht zunächst eine Dekodierung Base64->ASCII gelingt dies nicht, erscheint ein Hinweis und der eingegeben Text wird dann Base64-kodiert ausgegeben. """ + "\n\n") else: try: ascii_string = binascii.a2b_base64(eingabetext).decode() Ausgabe.insert(1.0, ascii_string + "\n") Ausgabe.insert(1.0, "Base64 -> ASCII:\n", "bu") except ValueError: base64_string = binascii.b2a_base64(eingabetext.encode()) Ausgabe.insert(1.0, base64_string.decode() + "\n") Ausgabe.insert(1.0, "ASCII -> Base64:\n", "bu") Ausgabe.insert(1.0, "Umwandlung Base64 -> ASCII war nicht möglich.\n", "re") def rail_encrypt(plain_text: str, rails: int): arr = [["" for _ in range(len(plain_text))] for _ in range(rails)] r = 0 z = 0 plus = True for b in plain_text: arr[r][z] = b z += 1 if r + 1 == rails and plus: plus = False r -= 1 elif r - 1 < 0 and not plus: plus = True r += 1 elif plus: r += 1 else: r -= 1 out = "" for i in range(rails): for j in range(len(plain_text)): out += arr[i][j] return out def jaegerzaun_encrypt(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.strip().replace("\n", " ") pw = PW_Eingabe.get() pw = pw.strip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [encrypt Jägerzaun] Jägerzaun (auch Railfence oder ZigZag-Chiffre genannt) Bei dieser Chiffre wird kodiert, indem man einen Text im Zickzackmuster in ein Feld aus z.B. 3 Zeilen und so vielen Spalten wie der Text lang ist schreibt. Man beginnt in Spalte 1 - Zeile 1, dann geht es in Spalte 2 - Zeile 1 weiter danach Spalte 3 - Zeile 3, dann Spalte 4 - Zeile 2, Spalte 5 - Zeile 1 usw. Danach werden die Buchstaben einfach Zeile für Zeile hintereinander geschrieben. Unterschiedliche Varianten entstehen einfach dadurch, dass man mit unterschiedlich vielen Zeilen arbeitet welche im Schlüsselfeld anzugeben ist. Die Funktion erzeugt hierbei einmal eine Ausgabe bei welcher auch Leerzeichen mitgeschrieben werden und eine Ausgabe wo zuvor die Leerzeichen entfernt werden. """ + "\n\n") elif pw == "" or not pw.isdigit(): Ausgabe.insert(1.0, "Bitte eine Zahl im Schlüsselfeld eingeben!!\n", "re") else: try: if int(pw) < 2: raise ValueError("Zahl zu klein") Ausgabe.insert(1.0, rail_encrypt(eingabetext.replace(" ", ""), int(pw)) + "\n") Ausgabe.insert(1.0, "ohne Leerzeichen\n", "bu") Ausgabe.insert(1.0, rail_encrypt(eingabetext, int(pw)) + "\n") Ausgabe.insert(1.0, "inkl. Leerzeichen\n", "bu") except ValueError: Ausgabe.insert(1.0, "Schlüsselzahl fehlerhaft oder kleiner als 2.\n", "re") def rail_decrypt(cipher: str, rails: int): arr = [["_" for _ in range(len(cipher))] for _ in range(rails)] # cipher ins array reinbasteln x, y = 0, 0 first_x = True for b in cipher: if x >= len(cipher) and y < rails: y += 1 x = y first_x = True arr[y][x] = b if y == 0 or (first_x and y != rails - 1): x = x + (rails - y - 1) * 2 first_x = False elif y == rails - 1 or first_x is False: x = x + (y * 2) first_x = True # dekodierten Text aus array holen out = "" x, y = 0, 0 down = True for _ in range(len(cipher)): out += arr[y][x] x += 1 if down and y + 1 == rails: down = False y -= 1 elif down: y += 1 elif down is False and y == 0: down = True y += 1 elif down is False: y -= 1 return out def jaegerzaun_decrypt(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.strip().replace("\n", " ") pw = PW_Eingabe.get() pw = pw.strip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [decrypt Jägerzaun] Jägerzaun (auch Railfence oder ZigZag-Chiffre genannt) Bei dieser Chiffre wird kodiert, indem man einen Text im Zickzackmuster in ein Feld aus z.B. 3 Zeilen und so vielen Spalten wie der Text lang ist schreibt. Man beginnt in Spalte 1 - Zeile 1, dann geht es in Spalte 2 - Zeile 1 weiter danach Spalte 3 - Zeile 3, dann Spalte 4 - Zeile 2, Spalte 5 - Zeile 1 usw. Danach werden die Buchstaben einfach Zeile für Zeile hintereinander geschrieben. Unterschiedliche Varianten entstehen einfach dadurch, dass man mit unterschiedlich vielen Zeilen arbeitet welche im Schlüsselfeld angegeben werden kann. Die Funktion erzeugt hierbei einmal eine Ausgabe bei welcher auch Leerzeichen mitgeschrieben werden und eine Ausgabe wo zuvor die Leerzeichen entfernt werden. Wird im Schlüsselfeld keine Zahl angegeben erfolgt automatisch die Dekodierung für alle Zeilenanzahlen von 2-12.""" + "\n\n") elif pw == "": for i in range(12, 1, -1): Ausgabe.insert(1.0, f'{i:02} - {rail_decrypt(eingabetext.replace(" ", ""), i)}\n') Ausgabe.insert(1.0, "ohne Leerzeichen\n", "bu") for i in range(12, 1, -1): Ausgabe.insert(1.0, f'{i:02} - {rail_decrypt(eingabetext, i)}\n') Ausgabe.insert(1.0, "inkl. Leerzeichen\n", "bu") elif not pw.isdigit(): Ausgabe.insert(1.0, "Bitte eine Zahl im Schlüsselfeld eingeben!!\n", "re") else: try: if int(pw) < 2: raise ValueError("Zahl zu klein") Ausgabe.insert(1.0, rail_decrypt(eingabetext.replace(" ", ""), int(pw)) + "\n") Ausgabe.insert(1.0, "ohne Leerzeichen\n", "bu") Ausgabe.insert(1.0, rail_decrypt(eingabetext, int(pw)) + "\n") Ausgabe.insert(1.0, "inkl. Leerzeichen\n", "bu") except ValueError: Ausgabe.insert(1.0, "Schlüsselzahl fehlerhaft oder kleiner als 2.\n", "re") def brainfuck_interpreter(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.rstrip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [Brainfuckinterpreter] !!!!!ACHTUNG DIESE FUNKTION KANN DAS PROGRAMM ZUM ABSTURZ BRINGEN!!!!! Brainfuck gehört zu den sogenannten esoterischen Programmiersprachen. Der Programmcode setzt sich hier aus den 8 Zeichen ><+-.,[]' zusammen. Diese Funktion führt einen derartigen Programmcode aus, und gibt das Ergebnis aus, welches bei Geocaches meist eine kurze Nachricht oder die Koordinaten sind. Für eine umgekehrte Umwandlung von Text in Brainfuckcode gibt es im Internet genügend Möglichkeiten zu finden. Folgender Code wäre z.B. "Hello World!" in Brainfuck: ++++++++++[>+++++++>++++++++++>+++>+<<<<-] >++.>+.+++++++..+++.>++.<<+++++++++++++++. >.+++.------.--------.>+.>.""" + "\n\n") else: # ein kleiner feiner Code von https://gist.github.com/kates/986792 c = [0] * 300000 p = 0 loop = [] rv = [] ts = list(eingabetext) li = len(ts) i = 0 while i < li: t = ts[i] if t == ">": p += 1 elif t == "<": p -= 1 elif t == "+": c[p] += 1 elif t == "-": c[p] -= 1 elif t == ".": rv.append(chr(c[p])) elif t == ",": pass elif t == "[": if c[p] == 0: while ts[i] != "]": i += 1 loop.pop() else: loop.append(i - 1) elif t == "]": i = loop[-1] i += 1 Ausgabe.insert(1.0, "".join(rv) + "\n") def ook_interpreter(): eingabetext = Eingabe.get(1.0, END) eingabetext = eingabetext.rstrip() if eingabetext == "": Ausgabe.insert(1.0, """HILFE: [Ook-Interpreter] !!!!!ACHTUNG DIESE FUNKTION KANN DAS PROGRAMM ZUM ABSTURZ BRINGEN!!!!! Ook ist eine Abwandlung von Brainfuck wobei die 8 Zeichen von Brainfuck hier durch eine Kombination von je zwei der folgenden 3 Satzzeichen .!? ersetzt werden. Dabei wird dann je das Wort Ook vor die Satzzeichen geschrieben. z.B.: Ook! Ook? Ook. Ook! Da Ook auch durch andere Wörter ersetzt oder auch ganz ohne Wörter (ShortOok) auftaucht ignoriert diese Funktion alle anderen Zeichen außer .!? bevor versucht wird den Code auszuführen.""" + "\n\n") else: ookzeichen = [".", "!", "?"] ooktext = "" for z in eingabetext: # erstmal Short-Ook draus machen if z in ookzeichen: ooktext = ooktext + z ookbf = {"..": "+", "!!": "-", ".?": ">", "?.": "<", "!?": "[", "?!": "]", "!.": ".", ".!": ","} bftext = "" for o in range(0, len(ooktext), 2): # jetzt in Brainfuck umwandeln ooz = ooktext[o:o + 2] if ooz in ookbf: bftext = bftext + ookbf[ooz] c = [0] * 300000 p = 0 loop = [] rv = [] ts = list(bftext) li = len(ts) i = 0 while i < li: t = ts[i] if t == ">": p += 1 elif t == "<": p -= 1 elif t == "+": c[p] += 1 elif t == "-": c[p] -= 1 elif t == ".": rv.append(chr(c[p])) elif t == ",": pass elif t == "[": if c[p] == 0: while ts[i] != "]": i += 1 loop.pop() else: loop.append(i - 1) elif t == "]": i = loop[-1] i += 1 Ausgabe.insert(1.0, "".join(rv) + "\n") '''