Menu
Coddy logo textTech

הסתרת מידע

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Python של Coddy. שיעור 30 מתוך 64.

הסתרת מידע מגבילה גישה ישירה לרכיבי אובייקט ומחייבת שכל האינטראקציות יתבצעו דרך ממשקים מוגדרים היטב. כך מוגנים הנתונים הפנימיים מפני גישה לא מורשית.

הנה דוגמה למחלקה עם רמות שונות של הסתרת מידע:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # ציבורי - ניתן לגשת אליו ישירות
        self._balance = initial_balance       # מוגן - לשימוש פנימי
        self.__account_number = "ACC123456"   # פרטי - מוסתר מגישה מבחוץ

הוסיפו מתודות שמספקות גישה מבוקרת לנתונים מוסתרים:

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):
        # דרך בטוחה להציג חלק מהמידע הפרטי
        return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"

השתמשו במחלקה דרך הממשק הציבורי שלה:

account = BankAccount("Alice", 1000)

גישה ישירה לנתונים ציבוריים:

print(account.owner)  # Alice - גישה ציבורית תקינה

השתמשו בשיטות מבוקרות לגישה לנתונים מוגנים:

print(account.get_balance())  # 1000 - גישה מבוקרת
account.deposit(500)
print(account.get_balance())  # 1500 - היתרה השתנתה באופן בטוח

נסה לגשת לנתונים מוסתרים:

print(account.get_account_info())  # בעלים: Alice, חשבון: ***3456
# print(account.__account_number)  # AttributeError - מוסתר

המאפיין הפרטי עובר שינוי שם, אך עדיין אפשר לגשת אליו מבחינה טכנית:

# זה עובד, אבל מפר את עקרון הסתרת המידע:
print(account._BankAccount__account_number)  # ACC123456

פלט:

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

נקודה מרכזית: הסתרת מידע מגנה על נתונים פנימיים בכך שהיא הופכת אותם לפרטיים או למוגנים, ואז מספקת גישה מבוקרת באמצעות מתודות ציבוריות. כך נמנעת מניפולציה ישירה של נתונים רגישים, ומובטחת שלמות הנתונים באמצעות אימות במתודות הגישה.

challenge icon

אתגר

בינוני

באתגר הזה תממשו מערכת הודעות מאובטחת עם בדיקות מקיפות לאימות הפתרון שלכם.

עליכם לערוך את securemessenger.py כדי לממש את המחלקה SecureMessenger בהתאם לעקרונות הסתרת מידע. הקובץ מכיל הערות TODO מפורטות שינחו אתכם במימוש.

הדרישות העיקריות כוללות:

  • כימוס נאות של פרטי הכניסה וההודעות
  • אימות לפני מתן אפשרות לביצוע פעולות בהודעות
  • ניטור אבטחה באמצעות מעקב אחר ניסיונות כניסה
  • הודעות החזרה מדויקות כפי שמפורטות בהערות ה-TODO

נסו בעצמכם

from securemessenger import SecureMessenger

# מטפל במקרי בדיקה
test_case = input()
if test_case == "default_test":
    # מקרה בדיקה סטנדרטי מהבעיה המקורית
    messenger = SecureMessenger("user1")
    
    # נסה להוסיף הודעות לפני ההתחברות
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # נסה להתחבר עם סיסמה שגויה
    print(messenger.login("wrong_pass"))
    
    # התחבר עם הסיסמה הנכונה
    print(messenger.login("secure123"))
    
    # הוסף הודעות לאחר התחברות מוצלחת
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # אחזר הודעות
    print(messenger.get_messages())
    
    # בדוק ניסיונות התחברות
    print(messenger.get_login_attempts())
elif test_case == "custom_password":
    # בדיקה עם סיסמה מותאמת אישית
    messenger = SecureMessenger("admin", "admin123")
    print(messenger.login("wrong_password"))
    print(messenger.login("admin123"))
    print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
    # בדיקה של ניסיונות התחברות מרובים
    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":
    # ניהול Test message
    messenger = SecureMessenger("user3")
    print(messenger.login("secure123"))
    
    # הוסף כמה הודעות
    messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
    for msg in messages:
        print(messenger.add_message(msg))
    
    # ודאו את כל ההודעות
    print(messenger.get_messages())
elif test_case == "empty_messages":
    # בדקו את המקרה של הודעות ריקות
    messenger = SecureMessenger("user4")
    print(messenger.login("secure123"))
    print(messenger.get_messages())
elif test_case == "access_without_login":
    # בדקו גישה ללא התחברות
    messenger = SecureMessenger("user5")
    print(messenger.add_message("Unauthorized message"))
    print(messenger.get_messages())
elif test_case == "attribute_privacy":
    # בדקו את פרטיות המאפיינים
    messenger = SecureMessenger("user6")
    
    # מאפיין ציבורי
    print(f"Public username: {messenger.username}")
    
    # מאפיינים פרטיים - אלה אמורים להעלות 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":
    # בדיקה זו דורשת להרחיב את המחלקה באמצעות מתודת logout
    # לצורך הבדיקה, ניצור תת־מחלקה עם יכולת logout
    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":
    # בדיקת עומס עם הודעות רבות
    messenger = SecureMessenger("user8")
    print(messenger.login("secure123"))
    
    # הוסיפו 100 הודעות
    for i in range(1, 101):
        messenger.add_message(f"Message {i}")
    
    # ודאו את מספר ההודעות
    messages = messenger.get_messages()
    newline_char = '\n'  # שמרו את תו ירידת השורה במשתנה
    message_count = len(messages.split(newline_char))
    print(f"Added 100 messages. Retrieved {message_count} messages.")
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Python אונליין