← Назад к вопросам
Проверка валидности IP адреса
2.0 Middle🔥 141 комментариев
#Теория тестирования
Условие
Напишите функцию, которая проверяет, является ли строка валидным IPv4 адресом.
Пример
Вход: 192.168.1.1 Выход: true
Вход: 256.1.1.1 Выход: false
Вход: 192.168.1 Выход: false
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Понимание задачи
Проверить валидность IPv4 адреса. Требования:
- Ровно 4 части (октета), разделённые точками
- Каждая часть — число от 0 до 255
- Нет пустых частей или символов кроме цифр и точек
Оптимальный алгоритм: Split + Валидация
def is_valid_ipv4(ip):
"""
Проверяет валидность IPv4 адреса.
"""
parts = ip.split('.')
# Должно быть ровно 4 части
if len(parts) != 4:
return False
for part in parts:
# Часть не должна быть пустой
if not part:
return False
# Все символы должны быть цифрами
if not part.isdigit():
return False
# Значение должно быть от 0 до 255
num = int(part)
if num < 0 or num > 255:
return False
# Нет ведущих нулей (кроме одного нуля)
if len(part) > 1 and part[0] == '0':
return False
return True
Как это работает
Пример 1: 192.168.1.1
Шаг 1: Split -> ['192', '168', '1', '1'] Шаг 2: Длина = 4 ✓ Шаг 3: Проверка каждой части:
- '192': все цифры ✓, 192 <= 255 ✓
- '168': все цифры ✓, 168 <= 255 ✓
- '1': все цифры ✓, 1 <= 255 ✓
- '1': все цифры ✓, 1 <= 255 ✓ Результат: True
Пример 2: 256.1.1.1
Шаг 1: Split -> ['256', '1', '1', '1'] Шаг 2: Длина = 4 ✓ Шаг 3: Проверка:
- '256': все цифры ✓, но 256 > 255 ✗ Результат: False
Сложность
- Временная: O(n) — где n длина строки
- Пространственная: O(1) — постоянное количество частей (4)
Расширенная версия с обработкой edge cases
def is_valid_ipv4_advanced(ip):
"""
Проверяет IPv4 с дополнительной обработкой ошибок.
"""
# Проверка типа входных данных
if not isinstance(ip, str):
return False
# Пустая строка
if not ip or ip.startswith('.') or ip.endswith('.'):
return False
# Слишком короткая строка
if len(ip) < 7: # Минимум: 1.1.1.1
return False
parts = ip.split('.')
if len(parts) != 4:
return False
for part in parts:
# Пустая часть
if not part:
return False
# Содержит только цифры
if not part.isdigit():
return False
# Ведущие нули (кроме '0')
if len(part) > 1 and part[0] == '0':
return False
# Значение в диапазоне
num = int(part)
if num > 255:
return False
return True
Тестирование
# Валидные IPv4
assert is_valid_ipv4('192.168.1.1') == True
assert is_valid_ipv4('0.0.0.0') == True
assert is_valid_ipv4('255.255.255.255') == True
assert is_valid_ipv4('127.0.0.1') == True
assert is_valid_ipv4('10.0.0.1') == True
# Невалидные IPv4
assert is_valid_ipv4('256.1.1.1') == False
assert is_valid_ipv4('192.168.1') == False
assert is_valid_ipv4('192.168.1.1.1') == False
assert is_valid_ipv4('192.168.01.1') == False # Ведущий ноль
assert is_valid_ipv4('192.168.-1.1') == False # Отрицательное
assert is_valid_ipv4('192.168.a.1') == False # Не цифры
assert is_valid_ipv4('.192.168.1.1') == False
assert is_valid_ipv4('192.168.1.1.') == False
assert is_valid_ipv4('') == False
assert is_valid_ipv4('...') == False
Альтернативные подходы
Способ 1: Регулярное выражение
import re
def is_valid_ipv4_regex(ip):
pattern = r'^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}' \
r'([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
return bool(re.match(pattern, ip))
- Одна строка
- Сложнее для понимания
- O(n) время
Способ 2: Try-except с socket (неоптимально)
import socket
def is_valid_ipv4_socket(ip):
try:
socket.inet_aton(ip)
return True
except socket.error:
return False
- Простой способ
- Зависит от стандартной библиотеки
- Может быть медленнее
Граничные случаи
# Граничные значения
assert is_valid_ipv4('0.0.0.0') == True
assert is_valid_ipv4('255.255.255.255') == True
assert is_valid_ipv4('256.0.0.0') == False
assert is_valid_ipv4('255.255.255.256') == False
# Ведущие нули
assert is_valid_ipv4('192.168.01.1') == False
assert is_valid_ipv4('0.0.0.0') == True # Один ноль OK
assert is_valid_ipv4('00.0.0.0') == False
# Неправильное количество частей
assert is_valid_ipv4('192.168.1') == False
assert is_valid_ipv4('192.168.1.1.1') == False
# Специальные символы
assert is_valid_ipv4('192.168.1.1a') == False
assert is_valid_ipv4('192.168.1.-1') == False
assert is_valid_ipv4('192 .168.1.1') == False
Выводы
- Split + валидация — простое и понятное решение
- O(n) время, O(1) доп. память — эффективно
- Ключевые проверки: количество частей, диапазон 0-255, ведущие нули
- Для QA: граничные значения, ведущие нули, спецсимволы, неправильное количество частей