0%
التحقق مما إذا كان عنوان IP خاصًا في Python

التحقق مما إذا كان عنوان IP خاصًا في Python

تعلّم كيف تحدد ما إذا كان عنوان IP خاصًا أم عامًا باستخدام Python ووحدة ipaddress. دليل شامل مع أمثلة عملية.

I

InSkillCoach

· دقيقة

التحقق مما إذا كان عنوان IP خاصًا في Python

تُستخدم عناوين IP الخاصة في الشبكات المحلية ولا يمكن توجيهها عبر الإنترنت. إن القدرة على التمييز بين عنوان IP خاص وعنوان عام مهارة أساسية في العديد من مهام إدارة الأنظمة وإعداد الشبكات وتطوير تطبيقات الشبكات.

نطاقات عناوين IP الخاصة

وفقًا للمعيار RFC 1918، فإن نطاقات عناوين IP الخاصة هي:

  • الفئة A: 10.0.0.0 - 10.255.255.255 (10.0.0.0/8)
  • الفئة B: 172.16.0.0 - 172.31.255.255 (172.16.0.0/12)
  • الفئة C: 192.168.0.0 - 192.168.255.255 (192.168.0.0/16)

لحسن الحظ، توفر لنا Python طريقة بسيطة للتحقق مما إذا كان عنوان IP ينتمي إلى هذه النطاقات بفضل وحدة ipaddress.

الطريقة 1: استخدام وحدة ipaddress (الموصى بها)

تأتي وحدة ipaddress ضمن المكتبة القياسية في Python منذ الإصدار 3.3، مما يجعلها الطريقة الموصى بها.

import ipaddress

def is_private_ip(ip_string):
    """
    التحقق مما إذا كان عنوان IP خاصًا.
    
    Args:
        ip_string (str): عنوان IP المراد التحقق منه على شكل سلسلة نصية (مثال: '192.168.1.1')
        
    Returns:
        bool: True إذا كان عنوان IP خاصًا، وإلا False
    """
    try:
        ip = ipaddress.ip_address(ip_string)
        return ip.is_private
    except ValueError:
        # معالجة الأخطاء إذا لم يكن المدخل عنوان IP صالحًا
        print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
        return False

# أمثلة على الاستخدام
test_ips = [
    '192.168.1.1',    # خاص (الفئة C)
    '10.0.0.1',       # خاص (الفئة A)
    '172.16.0.1',     # خاص (الفئة B)
    '8.8.8.8',        # عام (Google DNS)
    '127.0.0.1',      # Loopback (خاص)
    '172.32.0.1',     # عام (خارج النطاق الخاص مباشرة)
    '169.254.1.1',    # Link-local (خاص)
]

for ip in test_ips:
    result = "privée" if is_private_ip(ip) else "publique"
    print(f"{ip} est une adresse IP {result}")

النتيجة:

192.168.1.1 est une adresse IP privée
10.0.0.1 est une adresse IP privée
172.16.0.1 est une adresse IP privée
8.8.8.8 est une adresse IP publique
127.0.0.1 est une adresse IP publique  # Note: bien que spéciale (loopback), elle n'est pas classée comme privée
172.32.0.1 est une adresse IP publique
169.254.1.1 est une adresse IP publique  # Note: bien que spéciale (link-local), elle n'est pas classée comme privée

الطريقة 2: التنفيذ اليدوي

إذا لم تستطع استخدام وحدة ipaddress لأي سبب، فيمكنك تنفيذ التحقق يدويًا:

def is_private_ip_manual(ip_string):
    """
    التحقق يدويًا مما إذا كان عنوان IP خاصًا.
    
    Args:
        ip_string (str): عنوان IP المراد التحقق منه
        
    Returns:
        bool: True إذا كان عنوان IP خاصًا، وإلا False
    """
    try:
        # تحويل عنوان IP إلى قائمة من الأعداد الصحيحة
        octets = list(map(int, ip_string.split('.')))
        if len(octets) != 4 or any(octet < 0 or octet > 255 for octet in octets):
            raise ValueError("Format d'adresse IP invalide")
            
        # التحقق من نطاقات عناوين IP الخاصة
        # الفئة A: 10.0.0.0 - 10.255.255.255
        if octets[0] == 10:
            return True
            
        # الفئة B: 172.16.0.0 - 172.31.255.255
        if octets[0] == 172 and 16 <= octets[1] <= 31:
            return True
            
        # الفئة C: 192.168.0.0 - 192.168.255.255
        if octets[0] == 192 and octets[1] == 168:
            return True
            
        return False
        
    except (ValueError, IndexError):
        print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
        return False

التعامل مع عناوين IP الخاصة الخاصة

تتيح وحدة ipaddress أيضًا التعرف على أنواع أخرى من العناوين الخاصة:

import ipaddress

def check_ip_type(ip_string):
    """
    التحقق من نوع عنوان IP (خاص، loopback، link-local، إلخ.)
    
    Args:
        ip_string (str): عنوان IP المراد التحقق منه
        
    Returns:
        str: وصف نوع عنوان IP
    """
    try:
        ip = ipaddress.ip_address(ip_string)
        
        if ip.is_private:
            return "Adresse IP privée"
        elif ip.is_loopback:
            return "Adresse de loopback"
        elif ip.is_link_local:
            return "Adresse link-local"
        elif ip.is_multicast:
            return "Adresse multicast"
        elif ip.is_reserved:
            return "Adresse réservée"
        elif ip.is_global:
            return "Adresse IP publique (globale)"
        else:
            return "Autre type d'adresse"
            
    except ValueError:
        return "Adresse IP invalide"

# أمثلة على الاستخدام مع عناوين مختلفة
special_ips = [
    '192.168.1.1',    # خاص
    '10.0.0.1',       # خاص
    '127.0.0.1',      # Loopback
    '169.254.1.1',    # Link-local
    '224.0.0.1',      # Multicast
    '8.8.8.8',        # عام (Google DNS)
    '2001:db8::1',    # عنوان IPv6 للتوثيق
    'fe80::1',        # IPv6 link-local
]

for ip in special_ips:
    print(f"{ip}: {check_ip_type(ip)}")

التوافق مع IPv6

تتعامل وحدة ipaddress أيضًا مع عناوين IPv6:

import ipaddress

def is_private_ipv6(ip_string):
    """
    التحقق مما إذا كان عنوان IPv6 خاصًا.
    
    Args:
        ip_string (str): عنوان IPv6 المراد التحقق منه
        
    Returns:
        bool: True إذا كان عنوان IPv6 خاصًا، وإلا False
    """
    try:
        ip = ipaddress.ip_address(ip_string)
        return ip.is_private
    except ValueError:
        print(f"Erreur: {ip_string} n'est pas une adresse IP valide")
        return False

# أمثلة على عناوين IPv6
ipv6_addresses = [
    '2001:db8::1',          # عنوان للتوثيق (غير قابل للتوجيه)
    'fe80::1',              # Link-local
    'fd00::1',              # Unique Local Address (ULA) - المكافئ "الخاص" في IPv6
    '2001:4860:4860::8888', # عام (Google DNS)
]

for ip in ipv6_addresses:
    result = "privée" if is_private_ipv6(ip) else "publique"
    print(f"{ip} est une adresse IPv6 {result}")

حالات استخدام عملية

فيما يلي بعض حالات الاستخدام العملية لهذه الميزة:

  1. تصفية حركة المرور في تطبيق:
def process_connection(ip_address, data):
    if is_private_ip(ip_address):
        # معالجة الاتصالات الداخلية
        process_internal_connection(ip_address, data)
    else:
        # معالجة الاتصالات الخارجية
        # تطبيق إجراءات أمنية إضافية
        apply_security_measures(ip_address)
        process_external_connection(ip_address, data)
  1. التسجيل السياقي:
def log_access(ip_address, resource, action):
    ip_type = "interne" if is_private_ip(ip_address) else "externe"
    log_entry = f"{datetime.now()} - Accès {ip_type} depuis {ip_address} - {action} sur {resource}"
    logging.info(log_entry)
  1. التكامل مع أدوات مراقبة الشبكة:
def analyze_traffic_patterns(traffic_data):
    internal_traffic = {}
    external_traffic = {}
    
    for entry in traffic_data:
        ip = entry['source_ip']
        if is_private_ip(ip):
            if ip not in internal_traffic:
                internal_traffic[ip] = 0
            internal_traffic[ip] += entry['bytes']
        else:
            if ip not in external_traffic:
                external_traffic[ip] = 0
            external_traffic[ip] += entry['bytes']
    
    return {
        'internal_summary': internal_traffic,
        'external_summary': external_traffic
    }

الخلاصة

يُعد التحقق من عناوين IP الخاصة مهمة شائعة في برمجة الشبكات. وتُبسّط وحدة ipaddress في Python هذه العملية بشكل كبير بفضل الدالة is_private. وفي الحالات الأكثر تعقيدًا، توفر هذه الوحدة أيضًا دوال مفيدة أخرى مثل is_loopback وis_link_local وغيرها.

تفيد هذه الميزة بشكل خاص في:

  • تطوير تطبيقات شبكية آمنة
  • إعداد قواعد جدار الحماية
  • تحليل سجلات حركة المرور
  • التعامل بشكل مختلف مع الاتصالات الداخلية والخارجية

لمزيد من المعلومات، راجع التوثيق الرسمي لوحدة ipaddress.

InSkillCoach

نبذة عن InSkillCoach

خبير في التدريب والتقنيات

مدرّب متخصص في التقنيات المتقدمة والذكاء الاصطناعي، تدعمه شركة GNeurone Inc.

الشهادات:

  • AWS Certified Solutions Architect – Professional
  • شهادات Google Cloud
  • Microsoft Certified: DevOps Engineer Expert
  • Certified Kubernetes Administrator (CKA)
  • CompTIA Security+
1.9k
117

التعليقات

التعليقات مدعومة عبر GitHub Discussions

سجّل الدخول باستخدام GitHub للمشاركة في النقاش

تم نسخ الرابط!