Viết hàm kiểm tra chuỗi nhập vào là IPv4, IPv6 hợp lệ hay Neither.
Quy tắc định dạng
IPv4
- 4 nhóm số thập phân cách nhau bằng dấu chấm (
.). - Mỗi nhóm: 0–255.
- Không cho phép leading zero (ví dụ:
192.168.254.01sai).
IPv6
- 8 nhóm 4 chữ số hex cách nhau bằng dấu hai chấm (
:). - Mỗi nhóm: 0–FFFF (1–4 ký tự hex).
- Cho phép bỏ leading zero trong nhóm (ví dụ:
0db8→db8). - Không cho phép :: (nén nhóm 0 liên tiếp) để đơn giản hóa bài toán.
- Không cho phép leading zero thừa (ví dụ:
02001:...sai).
Thuật toán
- Tách chuỗi bằng
.→ nếu có 3 dấu chấm và mọi phần đều hợp lệ IPv4 → trả về "IPv4". - Tách chuỗi bằng
:→ nếu có 7 dấu hai chấm và mọi phần đều hợp lệ IPv6 → trả về "IPv6". - Ngược lại → "Neither".
Code Python
class Solution:
def validIPAddress(self, IP: str) -> str:
def is_ipv4(s: str) -> bool:
try:
# str(int(s)) == s loại bỏ leading zero (vd: "01" -> "1" != "01")
return str(int(s)) == s and 0 <= int(s) <= 255
except:
return False
def is_ipv6(s: str) -> bool:
if len(s) > 4:
return False
try:
# int(s, 16) parse hex; s[0] != '-' loại trừ dấu âm
return int(s, 16) >= 0 and s[0] != '-'
except:
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"
# Test
ob = Solution()
print(ob.validIPAddress("172.16.254.1")) # IPv4
print(ob.validIPAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334")) # IPv6
print(ob.validIPAddress("192.168.254.01")) # Neither (leading zero)
print(ob.validIPAddress("2001:0db8:85a3::8A2E:0370:7334")) # Neither (::)
Kết quả
IPv4
IPv6
Neither
Neither
Giải thích kỹ thuật
str(int(s)) == s: Kiểm tra leading zero rất khéo."01"→int→1→str→"1"≠"01".int(s, 16): Parse hex, tự động hiểu cả chữ hoa/thường.- Phương pháp này ngắn gọn, tận dụng exception handling của Python.