# Copyright (c) 2025 Martin Kayser (tebarius) # Licensed under the MIT License. See LICENSE file in the project root. import math from re import match # für unkennify import folium import streamlit as st from streamlit_folium import st_folium # ***recursive quersummenfunktion*** def q_sum(n): if n < 10: return n else: n = q_sum(n // 10) + n % 10 return n # ***recursive iterierte quersummenfunktion*** def iq_sum(n): if n < 10: return n else: n = iq_sum(q_sum(n)) return n # ***produziert eine Liste mit Primzahlen kleiner als grenze*** # ***nach dem Prinzip des "Sieb des Eratosthenes"*** @st.cache_resource def primzahlliste(grenze): primes = [] is_prime = [True] * grenze is_prime[0] = False is_prime[1] = False for i in range(2, int(math.sqrt(grenze))): if is_prime[i]: for j in range((i * i), grenze, i): is_prime[j] = False for i in range(len(is_prime)): if is_prime[i]: primes.append(i) return primes # ***alle permutationen generieren*** def all_perms(liste): if len(liste) <= 1: yield liste else: for perm in all_perms(liste[1:]): for i in range(len(perm) + 1): yield perm[:i] + liste[0:1] + perm[i:] # ***zählfunktionen für anagramm suche def buchstabenzaehl(buchstabe, anzahl): if buchstabe in anzahl: anzahl[buchstabe] = anzahl[buchstabe] + 1 else: anzahl[buchstabe] = 1 def wortzaehl(wort): anzahl = {} for buchstabe in wort: buchstabenzaehl(buchstabe.upper(), anzahl) return anzahl # ***Funktionen für Kachelkoordinaten/Maptiles-Funktion def dec_to_maptiles(lat_deg, lon_deg, zoom): lat_rad = math.radians(lat_deg) n = 2.0 ** zoom xtile = int((lon_deg + 180.0) / 360.0 * n) ytile = int((1.0 - math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi) / 2.0 * n) return xtile, ytile def maptiles_to_dec(xtile, ytile, zoom): n = 2.0 ** zoom lon_dec = xtile / n * 360.0 - 180.0 lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n))) lat_dec = math.degrees(lat_rad) return lat_dec, lon_dec # ***Dezimalgrad in Dezimalminuten (Ausgabe als String) def dec_to_deg(lat_dec, lon_dec): if lat_dec < 0: lat_pre = "S" else: lat_pre = "N" if lon_dec < 0: lon_pre = "W" else: lon_pre = "E" lat = abs(lat_dec) lon = abs(lon_dec) lat_degree = int(lat) lon_degree = int(lon) lat_minutes = (lat - lat_degree) * 60 lon_minutes = (lon - lon_degree) * 60 return ("{}{} {:.3f} {}{} {:.3f}".format(lat_pre, lat_degree, round(lat_minutes, 3), lon_pre, lon_degree, round(lon_minutes, 3))) # ***ReverseWherIGo zu Dezimalgrad def rwig_to_coords(a, b, c): lat, lon = 0, 0 a = int(a) b = int(b) c = int(c) if (a % 1000 - a % 100) / 100 == 1: lat_sign = 1 lon_sign = 1 elif (a % 1000 - a % 100) / 100 == 2: lat_sign = -1 lon_sign = 1 elif (a % 1000 - a % 100) / 100 == 3: lat_sign = 1 lon_sign = -1 elif (a % 1000 - a % 100) / 100 == 4: lat_sign = -1 lon_sign = -1 else: return 0, 0 if ((c % 100000 - c % 10000) / 10000 + (c % 100 - c % 10) / 10) % 2 == 0: lat = lat_sign * ( (a % 10000 - a % 1000) / 100 + (b % 100 - b % 10) / 10 + (b % 100000 - b % 10000) / 100000 + (c % 1000 - c % 100) / 10000 + (a % 1000000 - a % 100000) / 100000000 + (c % 100 - c % 10) / 100000 + a % 10 * 1.0E-5) elif ((c % 100000 - c % 10000) / 10000 + (c % 100 - c % 10) / 10) % 2 != 0: lat = lat_sign * ( (b % 1000000 - b % 100000) / 10000 + a % 10 + (a % 10000 - a % 1000) / 10000 + (c % 1000000 - c % 100000) / 10000000 + (c % 1000 - c % 100) / 100000 + (c % 100 - c % 10) / 100000 + (a % 1000000 - a % 100000) / 10000000000) if ((c % 100000 - c % 10000) / 10000 + (c % 100 - c % 10) / 10) % 2 == 0: lon = lon_sign * ( (a % 100000 - a % 10000) / 100 + (c % 1000000 - c % 100000) / 10000 + c % 10 + (b % 1000 - b % 100) / 1000 + (b % 1000000 - b % 100000) / 10000000 + (a % 100 - a % 10) / 10000 + (c % 100000 - c % 10000) / 100000000 + b % 10 * 1.0E-5) elif ((c % 100000 - c % 10000) / 10000 + (c % 100 - c % 10) / 10) % 2 != 0: lon = lon_sign * ( (b % 100 - b % 10) * 10 + c % 10 * 10 + (a % 100 - a % 10) / 10 + (a % 100000 - a % 10000) / 100000 + (b % 1000 - b % 100) / 10000 + b % 10 * 0.001 + (c % 100000 - c % 10000) / 100000000 + (b % 100000 - b % 10000) / 1000000000) return round(lat, 5), round(lon, 5) def unkennify(text): # Funktion hier entnommen und angepasst: https://www.namesuppressed.com/software/kenny.py decoded = '' codemap = str.maketrans('MmPpFf', '001122') n_len = len(text) i = 0 while i + 3 <= n_len: if match('[MmPpFf]{3,}', text[i:i + 3]): num = int(text[i:i + 3].translate(codemap), 3) # 'mpf' -> '012' -> 5 cypher = chr(num + ord('a')) # 5 -> 'f' if text[i].isupper(): cypher = cypher.upper() decoded = decoded + cypher i = i + 3 else: decoded = decoded + text[i] i = i + 1 if i < n_len: decoded = decoded + text[i:] return decoded 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 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 not down and y == 0: down = True y += 1 elif not down: y -= 1 return out #from folium.map import DivIcon def show_map_folium(df): if not df.empty: # Schritt 1: Bestimme die südwestliche und nordöstliche Ecke sw = df[['lat', 'lon']].min().values.tolist() # Südwesten ne = df[['lat', 'lon']].max().values.tolist() # Nordosten # Schritt 2: Initialisiere Karte (Ort egal, wird überschrieben, zoom wird bei mehreren Koordinaten überschrieben) m = folium.Map(location=df[["lat", "lon"]].mean().values.tolist(), zoom_start=15) # Schritt 3: Marker hinzufügen for _, row in df.iterrows(): if 'label' in row: folium.Marker( location=[row["lat"], row["lon"]], popup=f"{int(row['label'])}
Lat:{round(row['lat'], 5)}, Lon:{round(row['lon'], 5)}", tooltip=f"{int(row['label'])}
Lat:{round(row['lat'], 5)}, Lon:{round(row['lon'], 5)}", icon = folium.Icon(color="red", icon="map-marker") ).add_to(m) else: folium.Marker( location=[row["lat"], row["lon"]], popup=f"Lat:{round(row['lat'], 5)}, Lon:{round(row['lon'], 5)}", tooltip=f"Lat:{round(row['lat'], 5)}, Lon:{round(row['lon'], 5)}", icon = folium.Icon(color="red", icon="map-marker") ).add_to(m) if len(df) != 1: # Schritt 4: Zoom anpassen bei mehr als einer Koordinate m.fit_bounds([sw, ne]) # Schritt 5: In Streamlit anzeigen st_folium(m, use_container_width=True) else: st.markdown(":red[Keine sinnvoll darstellbaren Koordinaten gefunden]")