Misja Gynvaela 003

MISJA 003            goo.gl/ZPQvV0               DIFFICULTY: ██░░░░░░░░ [2/10]

Tym razem nie trzeba nic robić. Wystarczy uruchomić poniższy skrypt, chwilkę
poczekać, a hasło zostanie wypisane. No, taką dłuższą chwilkę...

#!/usr/bin/python
def magic1(a, b):
  o = 0
  i = 0
  while i < a:
    o += 1
    i += 1
  i = 0
  while i < b:
    o += 1
    i += 1
  return o
def magic2(a, b):
  o = 0
  i = 0
  while i < b:
    o = magic1(o, a)
    i += 1
  return o
n1 = int("2867279575674690971609643216365"
         "4161626212087501848651843132337"
         "3373323997065608342")
n2 = int("1240905467219837578349182398365"
         "3459812983123659128386518235966"
         "4109783723654812937")
n = magic2(magic1(n1, n2), 1337)
print hex(n)[2:-1].decode("hex").splitlines()[0]

Misja Gynvaela 002

MISJA 002                                        DIFFICULTY: ███░░░░░░░ [3/10]

Przechwyciliśmy fragment komunikacji pomiędzy dwoma podejrzanymi. Sądzimy, że
to hasło administratora do jednego z systemów, na których mogą znajdować się
kluczowe dla sprawy dane.

                 ╭┈┈                                     ┈┈╮  
                 ┊ QW== QT== QT== QQ== QU== Qd== QU== Qd== ┊
                   QX== QV== QW== Qe== QT== QR== QU== QT==
                   QT== QU== QX== QU== QT== QR== QT== QQ==
                 ┊ QW== Qe==               »goo.gl/4Iuxdi« ┊ 
                 ╰┈┈                                     ┈┈╯   

Niestety, pomimo, iż wiemy, że użyte zostało kodowanie Base64, nie jesteśmy w
stanie zdekodować ukrytej wiadomości. Nasi technicy uparcie twierdzą, że po
zdekodowaniu wychodzi „AAAAAAAAAAAAAAAAAAAAAAAAAA”, ale sądzimy, że nie mają
racji.

Zwracamy się więc do Ciebie z prośbą o pomoc - zrzuć okiem na powyższą
wiadomość i sprawdź czy nie ma czasem drugiego dna.

Jak przeładowywać operatory w mojej klasie?

Kiedy i które operatory przeładowywać?

Dość przewrotnie odpowiem: kiedy zajdzie taka potrzeba. Podstawą jest zachowanie logiki kodu (Samochod + Samochod nie ma zbyt sensu, ale Currency + Currency już tak) oraz konwencji języka (lub frameworka), np. w przypadku operatora <<.

Wyjście i wejście ze strumienia, czyli operatory << i >>

Tutaj nie ma wielkiej filozofii. Dobrze by było osiągnąć pełną serializację, t.j. zagwarantować poprawność kodu z listingu poniżej, ale w praktyce jest to więcej roboty niż to warte dla większości klas. Szczególnie, że nawet biblioteka standardowa nie zachowuje się w ten sposób, np. dla klasy std::string.

Jak łatwo zaimplementować w C++ operator porównania dla twojej klasy?

Biblioteka standardowa C++ w wielu miejscach oczekuje od typów, z którymi pracuje implementacji operatora< (alternatywą jest podanie własnego komparatora). Jest tak chociażby w std::sort, std::map lub std::binary_serch. Weźmy za przykład następującą klasę:

struct person
{
    string first_name;
    string last_name;
    string city;
    int year_born;
    bool is_male;
};

Aby posortować std::vector<person>, powinniśmy zaimplementować operator<, który spełnia strict weak ordering:

Bezpieczna zamiana jednostek w C++ część 1

sleep(300);

Ile śpimy? 0.3s (300ms)? 5 minut (300s)? A może parametrem powyższego sleep jest jeszcze inna jednostka? Bez zajrzenia do dokumentacji – albo kodu – nie ma na to pytanie odpowiedzi. Akurat w przypadku jednostek czasu C++11 wprowadził zestaw klas odpowiedzialnych za nie, więc można napisać taki zupełnie jednoznaczny kod:

this_thread::sleep_for(chrono::seconds(30));
this_thread::sleep_for(500ms); // C++14