Menu
Coddy logo textTech

Ukrywanie informacji

Część sekcji Programowanie obiektowe ścieżki Python w Coddy. Lekcja 30 z 64.

Ukrywanie informacji ogranicza bezpośredni dostęp do komponentów obiektu, wymagając, aby wszystkie interakcje odbywały się za pośrednictwem dobrze zdefiniowanych interfejsów. Chroni to dane wewnętrzne przed nieuprawnionym dostępem.

Oto przykład klasy z różnymi poziomami ukrywania informacji:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # Publiczny - można uzyskać bezpośredni dostęp
        self._balance = initial_balance       # Chroniony - do użytku wewnętrznego
        self.__account_number = "ACC123456"   # Prywatny - niedostępny z zewnątrz

Dodaj metody zapewniające kontrolowany dostęp do ukrytych danych:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner
        self._balance = initial_balance
        self.__account_number = "ACC123456"
        
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
            return True
        return False
    
    def withdraw(self, amount):
        if amount > 0 and amount <= self._balance:
            self._balance -= amount
            return True
        return False
    
    def get_balance(self):
        return self._balance
    
    def get_account_info(self):
        # Bezpieczny sposób wyświetlania części prywatnych danych
        return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"

Korzystaj z klasy za pośrednictwem jej publicznego interfejsu:

account = BankAccount("Alice", 1000)

Uzyskaj bezpośredni dostęp do danych publicznych:

print(account.owner)  # Alice - dostęp publiczny jest dozwolony

Używaj kontrolowanych metod dostępu do chronionych danych:

print(account.get_balance())  # 1000 - kontrolowany dostęp
account.deposit(500)
print(account.get_balance())  # 1500 - saldo zmienione w bezpieczny sposób

Spróbuj uzyskać dostęp do ukrytych danych:

print(account.get_account_info())  # Właściciel: Alice, Konto: ***3456
# print(account.__account_number)  # AttributeError - ukryty

Atrybut prywatny podlega modyfikacji nazwy, ale nadal jest technicznie dostępny:

# To działa, ale narusza zasadę ukrywania informacji:
print(account._BankAccount__account_number)  # ACC123456

Wynik:

Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456

Najważniejsza informacja: ukrywanie informacji chroni dane wewnętrzne, nadając im status prywatnych lub chronionych, a następnie zapewniając kontrolowany dostęp za pomocą metod publicznych. Zapobiega to bezpośredniej modyfikacji wrażliwych danych i zapewnia ich integralność dzięki walidacji w metodach dostępu.

challenge icon

Wyzwanie

Średni

W tym wyzwaniu zaimplementujesz bezpieczny system przesyłania wiadomości wraz z kompleksowymi testami, które zweryfikują Twoje rozwiązanie.

Musisz edytować plik securemessenger.py, aby zaimplementować klasę SecureMessenger zgodnie z zasadami ukrywania informacji. Plik zawiera szczegółowe komentarze TODO, które pomogą Ci w implementacji.

Najważniejsze wymagania:

  • Prawidłowa enkapsulacja danych logowania i wiadomości
  • Uwierzytelnianie przed zezwoleniem na operacje dotyczące wiadomości
  • Monitorowanie bezpieczeństwa poprzez śledzenie prób logowania
  • Precyzyjne komunikaty zwrotne określone w komentarzach TODO

Spróbuj swoich sił

from securemessenger import SecureMessenger

# Obsługa przypadku testowego
test_case = input()
if test_case == "default_test":
    # Standardowy przypadek testowy z oryginalnego zadania
    messenger = SecureMessenger("user1")
    
    # Spróbuj dodać wiadomości przed zalogowaniem
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Spróbuj zalogować się przy użyciu błędnego hasła
    print(messenger.login("wrong_pass"))
    
    # Zaloguj się przy użyciu poprawnego hasła
    print(messenger.login("secure123"))
    
    # Dodaj wiadomości po pomyślnym zalogowaniu
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Pobierz wiadomości
    print(messenger.get_messages())
    
    # Sprawdź próby logowania
    print(messenger.get_login_attempts())
elif test_case == "custom_password":
    # Test z niestandardowym hasłem
    messenger = SecureMessenger("admin", "admin123")
    print(messenger.login("wrong_password"))
    print(messenger.login("admin123"))
    print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
    # Test wielu prób logowania
    messenger = SecureMessenger("user2")
    print(messenger.login("attempt1"))
    print(messenger.login("attempt2"))
    print(messenger.login("attempt3"))
    print(messenger.login("secure123"))
    print(messenger.get_login_attempts())
elif test_case == "message_management":
    # Zarządzanie Test message
    messenger = SecureMessenger("user3")
    print(messenger.login("secure123"))
    
    # Dodaj wiele wiadomości
    messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
    for msg in messages:
        print(messenger.add_message(msg))
    
    # Sprawdź wszystkie wiadomości
    print(messenger.get_messages())
elif test_case == "empty_messages":
    # Przetestuj przypadek braku wiadomości
    messenger = SecureMessenger("user4")
    print(messenger.login("secure123"))
    print(messenger.get_messages())
elif test_case == "access_without_login":
    # Przetestuj dostęp bez logowania
    messenger = SecureMessenger("user5")
    print(messenger.add_message("Unauthorized message"))
    print(messenger.get_messages())
elif test_case == "attribute_privacy":
    # Przetestuj prywatność atrybutów
    messenger = SecureMessenger("user6")
    
    # Atrybut publiczny
    print(f"Public username: {messenger.username}")
    
    # Atrybuty prywatne — próba dostępu do nich powinna zgłosić AttributeError
    try:
        print(messenger.__password)
    except AttributeError as e:
        print("Password is private: AttributeError")
    
    try:
        print(messenger.__messages)
    except AttributeError as e:
        print("Messages are private: AttributeError")
    
    try:
        print(messenger.__login_attempts)
    except AttributeError as e:
        print("Login attempts are private: AttributeError")
    
    try:
        print(messenger.__is_logged_in)
    except AttributeError as e:
        print("Login status is private: AttributeError")
elif test_case == "login_logout_sequence":
    # Ten test wymaga rozszerzenia klasy o metodę logout
    # Na potrzeby testu utworzymy podklasę z możliwością wylogowania
    class ExtendedMessenger(SecureMessenger):
        def logout(self):
            self._SecureMessenger__is_logged_in = False
            return "Logged out successfully"
    
    messenger = ExtendedMessenger("user7")
    print(messenger.login("secure123"))
    print(messenger.add_message("Test message"))
    print(messenger.get_messages())
    print(messenger.logout())
    print(messenger.get_messages())
elif test_case == "stress_test":
    # Test obciążeniowy z wieloma wiadomościami
    messenger = SecureMessenger("user8")
    print(messenger.login("secure123"))
    
    # Dodaj 100 wiadomości
    for i in range(1, 101):
        messenger.add_message(f"Message {i}")
    
    # Sprawdź liczbę wiadomości
    messages = messenger.get_messages()
    newline_char = '\n'  # Zapisz znak nowej linii w zmiennej
    message_count = len(messages.split(newline_char))
    print(f"Added 100 messages. Retrieved {message_count} messages.")
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Python online