2012-08-04 82 views
17

有没有一种快速和肮脏的方式来验证是否输入了正确的FQDN?请记住,没有DNS服务器或Internet连接,因此验证必须通过regex/awk/sed完成。完全合格的域名验证

任何想法?

+0

不是真的..至少,它不会是可靠的。您可以通过保留您自己的顶级域名(它需要保持最新)列表来检查顶级域名(TLD)部分是否有效,但除此之外,我猜你的运气不佳:) – favoretti 2012-08-04 15:12:31

+1

试试这个,它是一个正则表达式: http://stackoverflow.com/questions/4912520/validate-fqdn-in-c-sharp – tombolinux 2012-08-04 16:31:44

+0

以及我的想法是验证用户输入了有效的DNS名称例如groupa-zone1appserver.example.com一个标准。 – Riaan 2012-08-04 16:38:55

回答

8

现在比较困难了,国际化域名和几千(!)个新TLD是什么。

最简单的部分是,您仍然可以在“。”上拆分组件。

您需要一个可注册顶级域名列表。有一个网站是:

https://publicsuffix.org/list/effective_tld_names.dat

你只需要检查ICANN认可的。请注意,可注册的TLD可以有多个组件,例如“co.uk”。

然后是IDN和punycode。现在域名是Unicode。例如,

“xn - nnx388a”相当于“台湾”。顺便说一下,这两个都是有效的顶级域名。

有关punycode转换代码,请参阅“http://golang.org/src/pkg/net/http/cookiejar/punycode.go”。

检查每个域组件的语法也有新的规则。请参阅RFC5890 http://tools.ietf.org/html/rfc5890

组件可以是A标签(仅限ASCII)或Unicode。 ASCII标签要么遵循旧的语法,要么开始“xn--”,在这种情况下,它们是一个Unicode字符串的punycode版本。

Unicode的规则非常复杂,并在RFC5890中给出。这些规则旨在防止诸如从左到右和从右到左组的字符混合。

对不起,没有简单的答案。

6

这正则表达式是你想要什么:

(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$) 

它符合你的榜样域(groupa-zone1appserver.example.com或cod.eu等)

我会试着解释:

(?=^.{1,254}$)匹配长度在1到254个字符之间的域名(可以以任何字符开头),如果我们假设co.uk是最小长度,它也可以是5,254。

(^起始匹配

(?:限定的匹配组

(?!\d+\.)域名不应由数字组成,所以1234.co.uk或abc.123.uk不同时1A接受。 ko.uk是的。

[a-zA-Z0-9_\-]域名应该由词语仅用-ZA-Z0-9_-

{1,63}的任何域级别的长度可以由是最大63字符,(也可能是2,63)

+

(?:[a-zA-Z]{2,})$)域名的最后部分不应被随后的任何其它的字,并且必须由至少2炭单词的-ZA-Z

+1

你想解释一下符号吗?它对'ac.uk'做了什么?这不是一个有效的FQDN;它是国家代码TLD下的一个中级域名。例如 – 2012-08-04 20:46:56

+0

aa.com是一个fqdn这个正则表达式只匹配由点划分的字符串,最后一个字符串是最小2字符。 – tombolinux 2012-08-04 21:07:42

+0

使用正则表达式,您只能匹配语法,而不是真正的dns fqdn。 – tombolinux 2012-08-04 21:20:16

31
(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$) 

正则表达式对于像这样的事情来说总是最好的近似值,并且规则会随着时间而改变。上面的正则表达式的写法注意以下几点:特定于主机名称 -

主机名由一系列与点连接的标签组成。 每个标签是1〜63个字符长,并且可以包含:

  • 的ASCII字母az(在不区分大小写的方式),
  • 数字0-9,
  • 和连字符(“ - “)。

此外:

一些假设:

  • TLD是至少2个字符,只有AZ
  • 我们至少需要1级以上TLD

结果:有效/无效

  • 911.gov - 有效
  • 911 - 无效(无TLD )
  • a-.com - 无效
  • -a.com - 无效
  • a.com - 有效
  • a.66 - 无效
  • my_host.com - 无效(undescore)
  • 典型-hostname33.whatever.co.uk - 有效

编辑: 约翰·里克斯所提供的正则表达式的替代黑客,使可选顶级域名的规范:

(?=^.{1,253}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63})$) 
  • 911 - 有效
  • 911.gov - 有效

编辑2: 有人问,在JS工作的版本。 它在js中不起作用的原因是因为js不支持正则表达式。 具体而言,代码(?<!-) - 它指定前一个字符不能是连字符。

反正这里被改写没有回顾后 - 有点丑陋,但没有太大的

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$) 

你同样可以让约翰·里克斯的版本类似的替代品。

编辑3:如果你要允许小圆点 - 这在技术上是允许的:

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}\.?$) 

我不熟悉尾随点语法,直到@ChaimKut指出出来,我做了一些研究

然而,使用尾随点似乎会在我玩过的各种工具中产生不可预测的结果,所以我会建议一些警告。

+1

这是一个(有点冒险的)替代版本,它也会验证没有关联域的主机名。任何改进? '(?=^{1254} $。)(^((( - )[A-ZA-Z0-9 - ] {1,63}(< - ))|?!?!?!(( - )[ a-zA-Z0-9 - ] {1,63}(?<! - )\。)+ [a-zA-Z] {2,63})$)' – 2014-06-30 16:07:08

+0

@John Rix:您的regex看起来像它但很多人复制/粘贴它会发现它失败,因为StackExchange为了格式化目的而将不可见字符插入注释的html源代码中 - 查看HTML源代码并查看http://meta.stackexchange.com/questions/170970/occasionally- -unicode-character-sequence-u200c-u200b-zwnj-zwsp-is-insert – bkr 2014-06-30 19:42:04

+0

感谢@bkr,并没有意识到这一点。不喜欢有一个解决方案,但至少你已经暴露了这个陷阱,为这里的外行! – 2014-07-01 08:25:28

1

审议#1:

请注意,由于在RFC-2181的DNS标签宽松的要求可以由符号(然而,长度的限制仍然存在)的几乎任意组合:

任何可以用作任何资源记录标签的二进制字符串DNS协议的实现不能对可以使用的标签进行任何限制,特别是DNS服务器不能拒绝服务区域,因为它包含标签这可能不被某些DNS客户端程序接受。“(https://tools.ietf.org/html/rfc2181#section-11

审议#2:

”有一个额外的规则,基本上需要顶级域名不是全数字“https://tools.ietf.org/html/rfc3696#section-2

考虑到这两个方面的考虑,正确的正则表达式如下:

/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i

看演示@http://regexr.com/3g5j0