Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

ตรวจสอบ IP Address ใน Python (IPv4 และ IPv6)

ในบทช่วยสอนนี้ เราจะเขียนฟังก์ชันตรวจสอบว่า string ที่ให้มาเป็น IPv4, IPv6 หรือ Neither (ไม่ใช่ทั้งคู่)

กฎการตรวจสอบ IPv4

  • รูปแบบ: 4 หมู่ตัวเลข คั่นด้วยจุด (.) เช่น 192.168.254.1
  • แต่ละหมู่: 0 - 255
  • ห้ามมี leading zeros (เช่น 192.168.254.01 ❌)

กฎการตรวจสอบ IPv6

  • รูปแบบ: 8 กลุ่ม hex digits 4 ตัว คั่นด้วย colon (:) เช่น 2001:0db8:85a3:0000:0000:8a2e:0370:7334
  • ย่อได้: leading zeros ในแต่ละกลุ่ม (เช่น 2001:db8:85a3:0:0:8A2E:0370:7334 ✅)
  • ห้ามใช้ :: (double colon) สำหรับกลุ่มศูนย์ติดกัน
  • ห้ามมี extra leading zeros (เช่น 02001:db8:... ❌)

อัลกอริทึม

  1. ฟังก์ชัน check_v4(part): ตรวจสอบว่า part เป็นตัวเลข 0-255 และไม่มี leading zeros
  2. ฟังก์ชัน check_v6(part): ตรวจสอบความยาว ≤ 4, เป็น hex valid, ไม่ขึ้นต้นด้วย -
  3. นับ delimiter: 3 จุด = IPv4 candidate, 7 colon = IPv6 candidate
  4. ตรวจสอบทุก part ตามกฎข้างต้น

การติดตั้ง (Python Implementation)

class Solution:
    def validIPAddress(self, IP: str) -> str:
        def is_ipv4(s: str) -> bool:
            try:
                # str(int(s)) == s -> กัน leading zeros (เช่น "01" -> "1" != "01")
                return str(int(s)) == s and 0 <= int(s) <= 255
            except ValueError:
                return False
        
        def is_ipv6(s: str) -> bool:
            if len(s) > 4:
                return False
            try:
                # int(s, 16) ตรวจสอบว่าเป็น hex valid, s[0] != '-' กันลบ
                return int(s, 16) >= 0 and s[0] != '-'
            except ValueError:
                return False
        
        if IP.count('.') == 3 and all(is_ipv4(part) for part in IP.split('.')):
            return "IPv4"
        if IP.count(':') == 7 and all(is_ipv6(part) for part in IP.split(':')):
            return "IPv6"
        return "Neither"

# ทดสอบ
ob = Solution()
print(ob.validIPAddress("172.16.254.1"))        # IPv4
print(ob.validIPAddress("192.168.254.01"))      # Neither (leading zero)
print(ob.validIPAddress("2001:0db8:85a3:0:0:8A2E:0370:7334"))  # IPv6
print(ob.validIPAddress("2001:0db8:85a3::8A2E:0370:7334"))     # Neither (::)
print(ob.validIPAddress("256.256.256.256"))     # Neither (>255)

Output

IPv4
Neither
IPv6
Neither
Neither

คำอธิบายเพิ่มเติม

  • str(int(s)) == s เป็นเทคนิคเช็ค leading zeros เรียบร้อย (แปลงเป็น int แล้วกลับ string เปรียบเทียบ)
  • int(s, 16) แปลง hex string เป็น integer ถ้า error แสดงว่าไม่ใช่ hex valid
  • ใช้ all() กับ generator expression เพื่อเช็คทุก part พร้อมกัน

สรุป

การ validate IP address ต้องระมัดระวัง edge cases มาก (leading zeros, ::, hex case) โค้ดข้างต้นจัดการครอบคลุมตามมาตรฐาน RFC


หากมีข้อสงสัย สามารถถามได้ในส่วนความคิดเห็นครับ