Проверьте доменные имена в соответствии со стандартом RFC 1035 в Java
Я пытаюсь написать код для проверки правильности доменных имен согласно стандарту rfc 1035 или нет. Стандарт RFC 1035 ( https://tools.ietf.org/html/rfc1035) имеет следующие критерии для доменных имен:
<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain> "." <label>
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> | "-"
<let-dig> ::= <letter> | <digit>
<letter> ::= any one of the 52 alphabetic characters A through Z in
upper case and a through z in lower case
<digit> ::= any one of the ten digits 0 through 9
Note that while upper and lower case letters are allowed in domain
names, no significance is attached to the case. That is, two names with
the same spelling but different case are to be treated as if identical.
The labels must follow the rules for ARPANET host names. They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen. There are also some
restrictions on the length. Labels must be 63 characters or less.
Я написал следующий фрагмент кода на Java, чтобы проверить, является ли имя домена действительным в соответствии с RFC 1035 или нет.
//DomainUtils.java
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class DomainUtils {
private static Pattern pDomainNameOnly1;
private static Pattern pDomainNameOnly2;
private static final String DOMAIN_NAME_PATTERN_CHK_1 = "^(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";
private static final String DOMAIN_NAME_PATTERN_CHK_2 = "^((?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)\\.)+(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";
static {
pDomainNameOnly1 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_1);
pDomainNameOnly2 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_2);
}
public static boolean isValidDomainName(String domainName) {
return (pDomainNameOnly1.matcher(domainName).find() || pDomainNameOnly2.matcher(domainName).find() || domainName.equals(" "));
}
}
а также
//Main.java
public class Main{
public static void main(String[] args){
boolean valid = DomainUtils.isValidDomainName("a123456789a123456789a123456789a123456789a123456789a1234567891234.ARPA"); //check if domain name is valid or not
System.out.println("Valid domain name : " + valid);
}
}
Я просто хотел проверить, есть ли какой-нибудь эффективный способ (кроме того, что я написал), чтобы проверить, является ли доменное имя действительным со стандартом RFC 1035? Также, если мне нужно проверить, работает ли мой код для угловых случаев по стандарту rfc 1035, то где я могу это проверить? Существуют ли какие-либо библиотеки, которые я могу использовать для этой проверки?
1 ответ
Попробуй это:
^[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$
как может быть показано в этой демонстрации
Чтобы построить это выражение, мы сначала используем компонент метки (один символ в наборе a-zA-Z
с последующим (необязательно) последовательностью символов в наборе a-zA-Z0-9-
и заканчивая не -
(дефис разрешен внутри, но не в начале или конце метки), приводящий к
[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?
это выражение повторяется по следующей схеме:
A(\.A)*
что означает последовательность A
с последующим любым числом (даже 0) последовательностей точки, за которой следует другой экземпляр A
,
Подставляя вышеупомянутые reges в позиции A, мы получаем окончательное регулярное выражение. Якоря исключают любые другие окружающие строки в начале / конце строки.
Чтобы проверить, что метки будут только до 63 символов, вы можете сделать
[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?
но будьте осторожны, так как это регулярное выражение компилируется в очень большой табличный автомат (автомат со многими состояниями), поэтому вам лучше расслабиться, если у вас мало места.