Проверка строки на соответствие правил именования DNS
Может, есть у кого готовый скрипт?
Есть строка вида device.domain.zone.
Необходимо её проверить на соответствие правилам именования DNS, то есть: англ. буквы, точка, тире, цифры, если что-то не так - выдать error. Как проверить - я примерно понимаю с помощью RegExp, но как проверить, чтобы в строке не было, допустим, 2-3-много точки подряд? 2-3 тире?
|
DJ Mogarych |
28-11-2019 16:44 2898374 |
Цитата:
Цитата glukin
соответствие правилам именования DNS, то есть: англ. буквы, точка, тире, цифры »
|
Точный критерий и несколько примеров правильных имён приведите.
Пока примерно так (powershell):
Код:
$dnsname = 'device.domain.zone.'
if ($dnsname -notmatch "^([A-Za-z0-9-]+\.){3}$" -or $dnsname -match "--") {
write-host -fore red "error!"
}
|
Цитата:
Цитата DJ Mogarych
Точный критерий и несколько примеров правильных имён приведите. »
|
Допустимы англ. буквы, точка, тире, цифры.
Device1.domain1.ru
device-2.domain.1.ru3
45-deVice.3.domain-4.5ru
Не должно быть более 1 точки или 1 тире подряд. Точка-тире или тире-точка или подобные сочетания недопустимы. На конце или в начале не может быть точек или тире.
|
DJ Mogarych |
29-11-2019 08:53 2898437 |
Тогда так:
Код:
if ($dnsname -notmatch "^([A-Za-z0-9-]+\.){2}[A-Za-z0-9-]+$" -or $dnsname -match "--|\.-|-\.|^[\.-]|[\.-]$") {
write-host -fore red "error!"
}
|
А на vbs можно? Ибо будет работать на win server 2003.
|
DJ Mogarych |
29-11-2019 11:04 2898461 |
Я не умею на VBS, тем более, что на Win2003 Powershell имеется.
|
Цитата:
Цитата DJ Mogarych
Win2003 Powershell имеется. »
|
Да не в этом дело, там уже есть гигантский скрипт на vbs, надо мне будет этот кусок туда внедрить.
Iska, Вы не поможете переделать сабж в vbs?
А если я сделаю так:
objShell.Run("powershell.exe -noexit -Command ""if ($dnsname -notmatch "^([A-Za-z0-9-]+\.){2}[A-Za-z0-9-]+$" -or $dnsname -match "--|\.-|-\.|^[\.-]|[\.-]$") {
write-host -fore red "error!"
}""")
то как сделать, чтобы вернуть в vbs-скрипт "error", если в результате команды powershell будет "error"? И как передать в powershell переменную dnsname?
|
Цитата:
Цитата glukin
там уже есть гигантский скрипт на vbs, надо мне будет этот кусок туда внедрить.
Iska, Вы не поможете переделать сабж в vbs? »
|
Покажите полный код Вашего скрипта (или файл скрипта, упаковав его в архив). Укажите в нём место, куда Вы планируете внедрять «этот кусок».
|
Цитата:
Цитата Iska
Покажите полный код Вашего скрипта »
|
А в личку или куда еще можно? Я бы не хотел его тут светить.
И, кстати,зачем?
|
Затем:
Цитата:
Цитата glukin
Не должно быть более 1 точки или 1 тире подряд. Точка-тире или тире-точка или подобные сочетания недопустимы. »
|
Точек подряд быть не может — это разделитель. Тире Дефис — может. Вы же не хотите отсечь национальные домены, в том числе такой домен, как, например, президент.рф :lol:?
Пример с шаблоном, найденным мною, и шаблоном коллеги DJ Mogarych:
Скрытый текст
Код:
Option Explicit
Dim arrDNSName
Dim objRegExp
Dim elem
arrDNSName = Array( _
"device.domain.zone", _
"Device1.domain1.ru", _
"device-2.domain.1.ru3", _
"45-deVice.3.domain-4.5ru", _
"45-deVice..domain-4.5ru", _
"45-deVice.3.domain--4.5ru", _
"45-deVice.3.domain-.5ru", _
"45-deVice.3.-domain.5ru", _
"45-deVice.3.domain-4.5ru." _
)
Set objRegExp = WScript.CreateObject("VBScript.RegExp")
objRegExp.IgnoreCase = False
objRegExp.Pattern = "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$"
For Each elem In arrDNSName
If objRegExp.Test(elem) Then
WScript.Echo "Match : " & elem
Else
WScript.Echo "Not match: " & elem
End If
Next
WScript.Echo "==============================================="
objRegExp.Pattern = "^([A-Za-z0-9-]+\.){2}[A-Za-z0-9-]+$"
For Each elem In arrDNSName
If objRegExp.Test(elem) Then
WScript.Echo "Match : " & elem
Else
WScript.Echo "Not match: " & elem
End If
Next
Set objRegExp = Nothing
WScript.Quit 0
|
Спасибо.
И всё-таки: точка-дефис или дефис-точка или подобные сочетания недопустимы.
Да,я хочу отсечь национальные домены, ибо DNS внутренний, а не интернетный.
|
Цитата:
Цитата glukin
И всё-таки: точка-дефис или дефис-точка или подобные сочетания недопустимы. »
|
Первое и второе недопустимы. Разве я сказал что-то другое?!
Цитата:
Цитата glukin
ибо DNS внутренний, а не интернетный. »
|
А какая разница? Пространство имён одинаково для всех. Реализации локальных серверов могут отличаться в ту или иную степень упоротости, хотите упарываться вослед — делайте, кто ж запретит.
|
Цитата:
Цитата Iska
Первое и второе недопустимы. »
|
Вроде бы, не совсем так:
Код:
<#
[enum]::GetNames("UriHostNameType")
Basic 1 узел установлен, однако не удается определить тип.
Dns 2 Имя узла представлено в виде DNS-имени.
IPv4 3 Имя узла представлено в формате IPv4.
IPv6 4 Имя узла представлено в формате IPv6.
Unknown 0 Тип имени узла не поддерживается.
#>
$arr = @(
"device.domain.zone"
"device.domain.zone."
".device.domain.zone"
"Device1.domain1.ru"
"device-2.domain.1.ru3"
"45-deVice.3.domain-4.5ru"
"45-deVice..domain-4.5ru"
"45-deVice.3.domain--4.5ru"
"45-deVice.3.domain-.5ru"
"45-deVice.3.-domain.5ru"
"45-deVice.3.domain-4.5ru."
)
$arr|%{ $_ + ' - ' + ([uri]::CheckHostName("$_"))}
|
YuS_2, я исходил из RFC 1034 - Domain names - concepts and facilities:
Цитата:
Код:
<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
|
Как можно увидеть, дефис ни в начале октета, ни в конце октета наличествовать не может. В начале октета может быть только буква, в конце октета — только буква или цифра.
|
Iska, октет тут наверное не при чём
glukin, сделайте простую проверку, какую сможете
а более строго проверит уже то ПО, которое будет эти данные использовать
|
Busla, не, тут смысл сделать проверку именно до ПО, так как оно не стартует с ошибочными dns-записями.
Iska, извините, забыл добавить, что "--" тоже недопустимо.
Вот это вроде работает, но пропускает "--"
^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$
|
Цитата:
Цитата Busla
Iska, октет тут наверное не при чём »
|
Да, попутал термины.
Цитата:
Цитата glukin
что "--" тоже недопустимо. »
|
Я же писал, с точки зрения RFC — допустимо.
Цитата:
Цитата glukin
Вот это вроде работает, но пропускает "--" »
|
Ну, дабы не усложнять регулярку, сделайте две проверки:
Скрытый текст
Код:
Option Explicit
Dim arrDNSName
Dim elem
arrDNSName = Array( _
"device.domain.zone", _
"Device1.domain1.ru", _
"device--2.domain.1.ru3", _
"45-deVice.3.domain-4.5ru", _
"45-deVice..domain-4.5ru", _
"45-deVice.3.domain--4.5ru", _
"45-deVice.3.domain-.5ru", _
"45-deVice.3.-domain.5ru", _
"45-deVice.3.domain-4.5ru." _
)
With WScript.CreateObject("VBScript.RegExp")
.IgnoreCase = False
For Each elem In arrDNSName
.Pattern = "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9]))*$"
If .Test(elem) Then
.Pattern = "-{2,}"
If Not .Test(elem) Then
WScript.Echo "Match : " & elem
Else
WScript.Echo "Not match: " & elem
End If
Else
WScript.Echo "Not match: " & elem
End If
Next
End With
WScript.Quit 0
|
Цитата:
Цитата Iska
я исходил из RFC 1034 - Domain names - concepts and facilities: »
|
Да, возможно, спорить не буду.
Просто, есть подозрение, что RFC датированный 1987 годом, наверное несколько устарел, к тому же, не думаю, что микрософт выпускает софт противоречащий неким стандартам доменных имен. Искать стандарты просто лень, но есть ссылка на документацию от микрософт.
|
Iska,
Цитата:
Цитата Iska
Ну, дабы не усложнять регулярку, сделайте две проверки »
|
Спасибо, вроде все как мне нужно работает! Тему можно закрывать.
|
Цитата:
Цитата YuS_2
к тому же, не думаю, что микрософт выпускает софт противоречащий неким стандартам доменных имен. »
|
«Произвольно расширяющий» или «Слишком широко трактующий» стандарты — легко! Примеров тому тьма: любая корпорация (или конгломерат корпораций), имеющая монопольное или близкое к нему положение на рынке или в своей (полу)закрытой нише, успела отметиться на данном поприще, что IBM, что Microsoft, что Apple, что Google и т.п.
Цитата:
Цитата YuS_2
Просто, есть подозрение, что RFC датированный 1987 годом, наверное несколько устарел, »
|
Вполне возможно, что и появились какие-то расширения его. Я тоже не стал глы́́боко копать в развитие :).
|
Цитата:
Цитата Iska
«Произвольно расширяющий» или «Слишком широко трактующий» стандарты — легко! »
|
Согласен, но только частично. То, что касается их собственных продуктов, они вольны создавать собственные стандарты или даже "соглашения", но что касается доменных имен (а сейчас мы говорим именно о них):
- тут им разгуляться особо негде, крылья будут быстро подрезаны. :)
|
YuS_2, у них там много чего разрешено:
Цитата:
Код:
PS C:\> [uri]::CheckHostName('device.doma_in.zone')
Dns
PS C:\> [uri]::CheckHostName('device.doma----in.zone')
Dns
PS C:\> [uri]::CheckHostName('260.260.260.260')
Dns
|
А вот тут: dns - Can (domain name) subdomains have an underscore "_" in it? - Stack Overflow идёт нешуточная битва как раз про это.
P.S. «После речи президента последует пресс-конференция о том, как следует понимать то, о чём он хотел сказать»™ :lol:.
|
Цитата:
Цитата Iska
у них там много чего разрешено »
|
это да. Но второй и третий, вроде не запрещено... буквы-цифры-и-дефис-между-ними. Там где 260, это не IP, так что вроде бы правильно определено...
Цитата:
Цитата Iska
После речи президента последует пресс-конференция о том, как следует понимать то, о чём он хотел сказать »
|
где-то, примерно так и есть, судя по той дискуссии... :)
|
Цитата:
Цитата glukin
уже есть гигантский скрипт на vbs, надо мне будет этот кусок туда внедрить. »
|
Значит, надо написать функцию, вызов которой можно вставить, например, в If, в аргументе которой DNS, а возвращает она или Истину (правильное DNS) или Ложь.
Если тупо решать задачу, как она поставлена, нагло заимствовать регулярку у Iska
Код:
MsgBox "Device1.domain1.ru" + " === " + CStr(X_DNS("Device1.domain1.ru"))
MsgBox "Device1.domain+1.ru" + " === " + CStr(X_DNS("Device1.domain+1.ru"))
MsgBox "Device1.domainЪ1.ru" + " === " + CStr(X_DNS("Device1.domainЪ1.ru"))
MsgBox "Device1..domain1.ru" + " === " + CStr(X_DNS("Device1..domain1.ru"))
MsgBox "Device1.domain1-.ru" + " === " + CStr(X_DNS("Device1.domain1-.ru"))
MsgBox ".Device1.domain1.ru" + " === " + CStr(X_DNS(".Device1.domain1.ru"))
MsgBox "Device1.domain1.ru-" + " === " + CStr(X_DNS("Device1.domain1.ru-"))
MsgBox "device-2.domain.1.ru3" + " === " + CStr(X_DNS("device-2.domain.1.ru3"))
MsgBox "45-deVice.3.domain-4.5ru" + " === " + CStr(X_DNS("45-deVice.3.domain-4.5ru"))
'''''''''''''''''''''''''''''
Function X_DNS(x)
X_DNS = True
With CreateObject("VBScript.RegExp")
.Pattern = "^([a-z0-9]|[a-z0-9][a-z0-9\-]{0,61}[a-z0-9])(\.([a-z0-9]|[a-z0-9][a-z0-9\-]{0,61}[a-z0-9]))*$"
.IgnoreCase = True
.Global = True
X_DNS = .Test(x)
If Not X_DNS Then Exit Function
End With
X_DNS_Err = Array("..", "--", "-.", ".-")
X_DNS_Err1 = Array(".", "-")
For Each X_DNS_i In X_DNS_Err
X_DNS = InStr(1, x, X_DNS_i) = 0
If Not X_DNS Then Exit Function
Next
For Each X_DNS_i In X_DNS_Err1
X_DNS = Left(x, 1) <> X_DNS_i And Right(x, 1) <> X_DNS_i
If Not X_DNS Then Exit Function
Next
End Function
|
Цитата:
Цитата YuS_2
Там где 260, это не IP, так что вроде бы правильно определено... »
|
Это-то понятно. Я про то, что — «гольные цифры», никаких там тебе:
Цитата:
<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
|
;).
|
Цитата:
Цитата Iska
Я про то, что — «гольные цифры», никаких там тебе »
|
Да, то, что является проверкой доменного имени в dotnet, явно не соответствует rfc1034. Ни объяснить, ни аргументировать это я не могу... тут только если микрософт соизволит пояснить свое творение, но для этого надо их как-то достать. У меня нет ни желания, ни возможностей для этого, так что воспримем это как данность. :)
|
Цитата:
Цитата YuS_2
У меня нет ни желания, ни возможностей для этого, так что воспримем это как данность. »
|
Присединюсь, коллега! :)
|
Цитата:
Цитата Iska
Пример с шаблоном, найденным мною, и шаблоном коллеги DJ Mogarych: »
|
А как в шаблон добавить "_", но чтобы нельзя было "__" или "._" или "_."? И чтобы с "_" не начиналось и не оканчивалось?
|
Ну, попробуйте (последние четыре элемента):
Скрытый текст
Код:
Option Explicit
Dim arrDNSName
Dim elem
arrDNSName = Array( _
"device.domain.zone", _
"Device1.domain1.ru", _
"device--2.domain.1.ru3", _
"45-deVice.3.domain-4.5ru", _
"45-deVice..domain-4.5ru", _
"45-deVice.3.domain--4.5ru", _
"45-deVice.3.domain-.5ru", _
"45-deVice.3.-domain.5ru", _
"45-deVice.3.domain-4.5ru.", _
"dev_ice.domain.ru", _
"dev__ice.domain.ru", _
"_device.domain.ru", _
"device_.domain.ru" _
)
With WScript.CreateObject("VBScript.RegExp")
.IgnoreCase = False
For Each elem In arrDNSName
.Pattern = "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-_]{0,61}[a-zA-Z0-9])(\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-_]{0,61}[a-zA-Z0-9]))*$"
If .Test(elem) Then
.Pattern = "-{2,}"
If Not .Test(elem) Then
.Pattern = "_{2,}"
If Not .Test(elem) Then
WScript.Echo "Match: " & elem
Else
WScript.Echo "Not match: " & elem
End If
Else
WScript.Echo "Not match: " & elem
End If
Else
WScript.Echo "Not match: " & elem
End If
Next
End With
WScript.Quit 0
|
Iska, спасибо! Все работает прекрасно.
|
Время: 02:13.
© OSzone.net 2001-