Как я могу проверить, что доменное имя соответствует RFC 1035 с использованием Python?
Я пытаюсь написать код, который будет принимать "предполагаемое" доменное имя и проверять его в соответствии с RFC 1035. Например, он должен удовлетворять следующим правилам:
- Домен состоит не более чем из 253 символов.
- Набор символов домена
[a-z0-9\-]
только (нижний регистр домена на входе) - Домен не может содержать две последовательные черты (например:
google--com.com
) - Максимальный лимит поддоменов составляет 127
Я искал различные модули Python (например, tldextract), но безрезультатно.
Как я могу проверить, что доменное имя соответствует RFC 1035?
2 ответа
ПОЦЕЛУЙ:
import string
VALID_CHARS = string.lowercase + string.digits + '-.'
def is_valid_domain(domain):
if not all(char in VALID_CHARS for char in domain.lower()):
return False
if len(domain) > 253:
return False
if '--' in domain:
return False
if '..' in domain:
return False
return True
Есть времена для ловкости, но, похоже, это не один из них.
Я думаю, что это довольно просто решить самостоятельно, если вас интересуют только домены RFC 1035. Более поздние спецификации допускают больше видов доменных имен, так что этого будет недостаточно для реального мира!
Вот решение, которое использует регулярное выражение для сопоставления доменных имен, которые следуют "предпочтительному синтаксису имени", описанному на страницах 6 и 7 RFC. Он обрабатывает все, кроме ограничения верхнего уровня на количество символов с одним шаблоном:
import re
def validate_domain_name(name):
if len(name) > 255: return False
pattern = r"""(?X) # use verbose mode for this pattern
^ # match start of the input
(?: # non-capturing group for the whole name
[a-zA-Z] # first character of first label
(?: # non-capturing group for the rest of the first label
[a-zA-Z0-9\-]{,61} # match middle characters of label
[a-zA-Z0-9] # match last character of a label
)? # characters after the first are optional
(?: # non-capturing group for later labels
\. # match a dot
[a-zA-Z](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])? # match a label as above
)* # there can be zero or more labels after the first
)? # the whole name is optional ("" is valid)
$ # match the end of the input"""
return re.match(pattern, name) is not None # test and return a Boolean