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

Validate IPv6 Address ด้วย Regex ใน C++

โจทย์

ตรวจสอบว่า String เป็น IPv6 Address ที่ถูกต้องหรือไม่ ใช้ Regular Expression (Regex)

รูปแบบ IPv6

  • 8 กลุ่ม (Groups) คั่นด้วย Colon (:)
  • แต่ละกลุ่ม: 1-4 Hexadecimal Digits (0-9, a-f, A-F)
  • Leading zeros อนุญาต (แตกต่างจาก IPv4)
  • ตัวอย่าง: 2001:0db8:85a3:0000:0000:8a2e:0370:7334

Regex Pattern


^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})$

โค้ด C++


#include <bits/stdc++.h>
using namespace std;

string validateIPv6(string IP) {
    // Full IPv6: 8 groups of 1-4 hex digits
    regex ipv6(R"(^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})$)");
    
    if (regex_match(IP, ipv6)) {
        return "IPv6";
    }
    return "Not";
}

int main() {
    vector<string> tests = {
        "2001:0db8:85a3:0000:0000:8a2e:0370:7334", // Valid
        "3001:0da8:82a3:0:0:8B2E:0270:7224",       // Invalid (3001 > FFFF? Actually valid hex but 3001 is ok)
        "2001:db8:85a3:0:0:8A2E:370:7334",         // Valid (compressed zeros)
        "2001:0db8:85a3::8a2e:0370:7334",          // Invalid for this regex (:: not handled)
        "2001:0db8:85a3:00000:8a2e:0370:7334",     // Invalid (5 digits)
        "2001:0db8:85a3:0000:8a2e:0370:7334",      // Invalid (only 7 groups)
        "2001:0db8:85a3:0000:0000:8a2e:0370:7334:", // Invalid (trailing colon)
        "::1",                                     // Invalid for this regex (compressed)
        "2001:db8::1",                             // Invalid for this regex (compressed)
    };
    
    for (auto& ip : tests) {
        cout << ip << " → " << validateIPv6(ip) << endl;
    }
    
    return 0;
}

หมายเหตุสำคัญ: IPv6 Compression

Regex ข้างต้น ไม่รองรับ IPv6 Compressed Format เช่น:

  • :: แทนกลุ่มศูนย์ติดกันหลายกลุ่ม (ใช้ได้ 1 ครั้งต่อ Address)
  • 2001:db8::1 = 2001:0db8:0000:0000:0000:0000:0000:0001
  • ::1 = Loopback

Regex รองรับ Compression (ซับซ้อนกว่า)


// Simplified: รองรับ :: ครั้งเดียว
regex ipv6Compressed(R"(^(
    ([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|           # Full
    (([0-9a-fA-F]{1,4}:){1,7}:)|                       # End ::
    (([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4})|      # Mid ::
    (([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2})|
    (([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3})|
    (([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4})|
    (([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5})|
    ([0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6}))|
    (:((:[0-9a-fA-F]{1,4}){1,7}|:))                    # Start ::
)$)");

ผลลัพธ์ (Basic Regex)

2001:0db8:85a3:0000:0000:8a2e:0370:7334 → IPv6
3001:0da8:82a3:0:0:8B2E:0270:7224 → IPv6
2001:db8:85a3:0:0:8A2E:370:7334 → IPv6
2001:0db8:85a3::8a2e:0370:7334 → Not
2001:0db8:85a3:00000:8a2e:0370:7334 → Not
2001:0db8:85a3:0000:8a2e:0370:7334 → Not
2001:0db8:85a3:0000:0000:8a2e:0370:7334: → Not
::1 → Not
2001:db8::1 → Not

สรุป

Basic IPv6 Validation ด้วย Regex ง่ายสำหรับ Full Format (8 Groups) แต่ Real-world ต้องรองรับ Compression (::) ซึ่ง Regex ซับซ้อนมาก แนะนำใช้ Library (boost::asio::ip::address_v6, inet_pton) แทน