Coding Challenge w Grazu: Zwycięzcą został..
Podczas Graz Linux Days, grommunio było gospodarzem cieszącego się dużym uznaniem wyzwania kodowania. Spośród 23 uczestników, 9 było w stanie zaprezentować udane wyniki. Zwycięzca nagrody głównej, wyłoniony w drodze losowania, odebrał już swoją nagrodę w biurze grommunio.

Fabian Ortner z grommunio prezentuje nowiutką konsolę Sony PlayStation 5, wartą prawie 700 euro, szczęśliwemu zwycięzcy Andreasowi.
Brzmi to całkiem prosto, prawda?
“W tym zadaniu musisz napisać kod C/C++ w pliku \src\main.cpp, aby rozwiązać wyzwanie kodowania na końcu tego pliku Readme. Używany jest MinGW64 z gcc/g++ 15.2, który jest automatycznie konfigurowany w lokalnym katalogu i może być używany z następującymi poleceniami. ”
To, co może brzmieć niezrozumiale dla wielu nietechnicznych osób, nie wydaje się trudne dla programistów - przynajmniej na pierwszy rzut oka. Zasadniczo, cztery zadania zawarte w grommunio były z pewnością możliwe do rozwiązania, więc 23 ekspertów Linuksa podjęło wyzwanie w pewną kwietniową sobotę w Grazu.
Programowanie pod presją czasu
Wielu uczestników zmagało się z limitem czasu, w którym musieli znaleźć prawidłowe rozwiązanie przy użyciu kodu, który sami napisali. Początkowe oszacowanie 20 minut okazało się zbyt optymistyczne; nawet w ciągu ostatnich 40 minut tylko 9 uczestników było w stanie znaleźć prawidłowe rozwiązania.
W rezultacie dwa specjalnie przygotowane komputery z systemem Windows w Grazu były zajęte niemal bez przerwy w sobotę, z ponad siedmioma godzinami przeznaczonymi na samo wyzwanie.
Konfiguracja Coding Challenge
pracownicy grommunio utworzyli nowe konta użytkowników na komputerach, skonfigurowali VSCode jako edytor i zautomatyzowali różne polecenia za pomocą skryptów cmd systemu Windows, aby przyspieszyć proces kompilacji i przesyłania.

Uczestnik, który pomyślnie ukończył wyzwanie za pomocą narzędzi dostarczonych przez grommunio.
“Skonfigurowaliśmy mały punkt końcowy HTTP, który w połączeniu ze skryptem powłoki na komputerach biorących udział w wyzwaniu, pozwolił nam wygenerować spersonalizowane dane wejściowe dla każdego uczestnika na podstawie jego adresu e-mail, a następnie odpowiedzieć z informacją zwrotną na temat jego prób rozwiązania problemu ” - wyjaśnia Fabian Ortner z grommunio (na zdjęciu powyżej). “Plik Readme zawierał następnie bardziej szczegółowy opis tego, co należy zrobić w celu wykonania zadania programistycznego, a zatem stworzono dość prosty, zautomatyzowany proces, aby maksymalnie ułatwić uczestnictwo. ”
Ale część “tak prosta, jak to tylko możliwe” nie trwała długo. W ramach wyzwania uczestnicy musieli naprawić nieprawidłowo działający serwer pocztowy, pisząc mały skrypt konwersji. W README, pierwsze z czterech zadań do rozwiązania zaczyna się od:
“Wygląda na to, że każda linia zawiera całkowitą wielokrotność 8 znaków, więc spróbujmy zinterpretować je jako pojedyncze bajty. Na przykład:
*010001000101000101001010 0x44 0x51 0x4A 010001000101000001001100 => 0x44 0x50 0x4C 010000100101000101001100 0x42 0x51 0x4C *
Wiemy, że stary serwer pocztowy używał bardzo prostej metody szyfrowania po wyeksportowaniu wiadomości e-mail:
- Bierzemy każdy wiersz tekstu, czyli każdy bajt
- Dla każdej linii wykonaj szyfrowanie XOR z kluczem `grommunio`, znak po znaku
- *Jeśli linia jest dłuższa niż klucz, po prostu zastosuj klucz ponownie, zaczynając od pierwszego znaku”
Pojawiły się kolejne wymagania i zadania, od których naprawdę zakręciło się w głowie. Tylko nieliczni uczestnicy byli w stanie wymyślić poprawne rozwiązania.
Ale nawet ci, którym się nie udało, mieli na co czekać: w końcu losowanie wśród wszystkich uczestników zadecydowało o tym, kto otrzyma obiecane PlayStation. Zwycięzca Andreas został zaproszony do odebrania jej na 30. piętrze DC Tower w Wiedniu, w siedzibie grommunio.
Rozwiązanie? Nie zostanie ono tutaj opublikowane, ale plik README z pełnym opisem problemu jest dostępny pod tym postem. Jednak bez serwera zbudowanego przez grommunio na Graz Linux Days, będzie to wymagało trochę wyobraźni..
Dowiedz się więcej o grommunio na Graz Linux Days w tym artykule.
Coding Challenge Instructions
To wyzwanie wymaga napisania kodu C/C++ wewnątrz pliku .\src\main.cpp w celu rozwiązania zadania znajdującego się na końcu niniejszej instrukcji. Używa MinGW64 z gcc/g++ 15.2, który jest automatycznie konfigurowany w lokalnym katalogu i może być używany z następującymi poleceniami.
Istnieją cztery ważne polecenia dla dołączonego skryptu:
1. Aby zarejestrować swój adres e-mail i uruchomić 20-minutowy licznik czasu:
.\glt.cmd start
2. Aby po prostu zbudować swój kod:
.\glt.cmd build
3. Aby zbudować i uruchomić kod oraz wydrukować jego dane wyjściowe w terminalu:
.\glt.cmd build_and_run
4. Aby zbudować, uruchomić i przesłać rozwiązanie:
.\glt.cmd submit
Polecenie używane do kompilowania rozwiązania domyślnie nie ma włączonych optymalizacji:
g++.exe -static -O0 -g -std=c++17 src\main.cpp -o build/app.exe
Challenge
Aby rozpocząć wyzwanie, najpierw umieść swój adres e-mail w pliku user.txt, a następnie użyj komendy start, aby uzyskać swoje dane wejściowe. Używamy go tylko do kontaktu w przypadku wygrania losowania. Musisz tylko zmienić zmienną result w swoim kodzie, a następnie uruchomić polecenie submit, aby sprawdzić, czy jest poprawna.
WOW. Co się stało z tym e-mailem podczas migracji? W jakiś sposób jedna z wiadomości e-mail została uszkodzona podczas konfiguracji nowego serwera pocztowego. Wygląda na to, że składa się tylko z symboli binarnych podzielonych na kilka linii (dane wejściowe). Wydaje się, że w każdej linii znajduje się całkowita wielokrotność 8 symboli, więc spróbujmy zinterpretować je jako pojedyncze bajty. Na przykład:
010001000101000101001010 0x44 0x51 0x4A 010001000101000001001100 => 0x44 0x50 0x4C 010000100101000101001100 0x42 0x51 0x4C
Wiemy, że stary serwer pocztowy używał naprawdę prostego szyfrowania po wyeksportowaniu wiadomości e-mail:
- Weź każdą linię tekstu, tj. każdy bajt
- XOR każdej linii z kluczem grommunio po znakach
- Jeśli linia jest dłuższa niż klucz, po prostu użyj klucza ponownie, zaczynając od pierwszego znaku.
0x44 ^ g = 0x23 0x51 ^ r = 0x23 0x4A ^ o = 0x25 0x44 ^ g = 0x23 0x50 ^ r = 0x22 0x4C ^ o = 0x23 0x42 ^ g = 0x25 0x51 ^ r = 0x23 0x4C ^ o = 0x23
Wygląda to już bardziej obiecująco, ale nadal jest wiele pomieszanych znaków..
W dawnych czasach stary serwer pocztowy miał już problemy z przesunięciami poszczególnych wartości znaków, przy czym przesunięcie zależało od dwóch rzeczy:
- poziomej sumy kontrolnej adresu e-mail
- indeksu znaku w linii i numeru linii, w której się znajduje
W tym czasie serwer obliczał poziomą sumę kontrolną, po prostu dodając do siebie wszystkie wartości bajtów adresu e-mail.
max.mustermann@grommunio.com => (m=109) + (a=97) + (x=120) + … = 2888
Następnie dla każdego znaku obliczono jego dodatnie przesunięcie, biorąc sumę kontrolną modulo jego pozycję w linii. Aby skorygować ten błąd, musimy zatem odjąć wartości przesunięcia od każdego z bajtów. Dodatkowo te przesunięcia są następnie przesuwane w lewo o jeden znak po każdej linii.
0x23 - (2888 % 1) = ’#’ 0x23 - (2888 % 2) = ’#’ 0x25 - (2888 % 3) = ’#’ 0x23 - (2888 % 2) = ’#’ 0x22 - (2888 % 3) = ’ ’ 0x25 - (2888 % 1) = ’#’ 0x23 - (2888 % 3) = ’#’ 0x23 - (2888 % 1) = ’#’ 0x25 - (2888 % 2) = ’#’
Teraz wygląda to na poprawną wiadomość! Ale aby upewnić się, że mamy poprawny algorytm, musimy obliczyć iloczyn pierwiastków wartości przesunięcia razy wartości znaków każdego użytego znaku klucza i zsumować je dla każdego znaku # w wiadomości. (\n i \r powinny zostać odrzucone)
(g=103)\*0 + (r=114)\*0 + (o=111)\*2
- (g=103)*0 + (o=111)*0
- (g=103)*2 + (r=114)*0 + (o=111)*0 = 428
Aby ukończyć Wyzwanie Kodowania, należy zapisać tę sumę iloczynów mądrych pierwiastków w zmiennej wynikowej!