需要从主机名转到基础域

时间:2016-12-19 18:32:38

标签: tsql powershell fqdn

我需要一个功能:

f(fqdn,suffix) -> basedomain

使用这些示例输入和输出:

f('foobar.quux.somedomain.com','com') -> 'somedomain.com'
f('somedomain.com','com') -> 'somedomain.com'
f('foobar.quux.somedomain.com.br','com.br') -> 'somedomain.com.br'
f('somedomain.com.br','com.br') -> 'somedomain.com.br'

简单地说,如果suffix包含n个细分受众群,请选择最后n+1个细分受众群。找到FQDN的基本域,允许一些FQDN具有多个后缀元素。

我需要匹配的后缀是here。我已经把它们放在我的SQL数据库中了。

我可以用C#写这个;它可能不是最优雅但它会起作用。不幸的是,我希望在最接近数据的T-SQL或Powershell中使用此函数,这是使用此数据的其余实用程序所在的位置。我想可以在C#中编译,编译成程序集然后从T-SQL,甚至从Powershell访问它......如果那是最快的执行。如果在纯T-SQL或简单的Powershell中有一些相当聪明的选择,我会喜欢它。

编辑:有一件事我忘了明确提到(但在查看后缀列表时,在我上面的链接中很清楚)是我们必须选择最长的匹配后缀。 “br”和“com.br”都出现在后缀列表中(类似的事情发生在英国,pt等)。所以SQL必须使用窗口函数来确保找到最长的匹配后缀。

这是我在做SQL时有多远。我在所有substring / reverse函数中迷失了方法。

SELECT Domain, suffix
FROM (
    SELECT SD.Domain, SL.suffix, 
       RN=ROW_NUMBER() OVER (
           PARTITION BY sd.Domain ORDER BY LEN(SL.suffix) DESC)
    FROM SiteDomains SD
    INNER JOIN suffixlist SL ON SD.Domain LIKE '%.'+SL.suffix
) AS X
WHERE RN=1

这适用于找到正确的后缀。我对它的性能有点担心。

3 个答案:

答案 0 :(得分:2)

以下演示了将FQDN与TLD匹配并提取所需的 n + 1 域名段:

-- Sample data.
declare @SampleTLDs as Table ( TLD VarChar(64) );
insert into @SampleTLDs ( TLD ) values
  ( 'com' ), ( 'somedomain.com' ), ( 'com.br' );
declare @SampleFQDNs as Table ( FQDN VarChar(64) );
insert into @SampleFQDNs ( FQDN ) values
  ( 'foobar.quux.somedomain.com' ), ( 'somedomain.com' ),
  ( 'foobar.quux.somedomain.com.br' ), ( 'somedomain.com.br' );
select * from @SampleTLDs;
select * from @SampleFQDNs;

-- Fiddle about.
select FQDN, TLD,
  case
    when DotPosition = 0 then FQDN
    else Reverse( Left( ReversedPrefix, DotPosition - 1) ) + '.' + TLD
    end as Result
  from (
    select FQDNs.FQDN, TLDs.TLD,
      Substring( Reverse( FQDNs.FQDN ), Len( TLDs.TLD ) + 2, 100 ) as ReversedPrefix,
      CharIndex( '.', Substring( Reverse( FQDNs.FQDN ), Len( TLDs.TLD ) + 2, 100 ) ) as DotPosition
      from @SampleFQDNs as FQDNs inner join
        @SampleTLDs as TLDs on FQDNs.FQDN like '%.' + TLDs.TLD or FQDNs.FQDN = TLDs.TLD  ) as Edna;

-- To select only the longest matching TLD for each FQDN:
with
  ExtendedFQDNs as (
    select FQDNs.FQDN, TLDs.TLD, Row_Number() over ( partition by FQDN order by Len( TLDs.TLD ) desc ) as TLDLenRank,
      Substring( Reverse( FQDNs.FQDN ), Len( TLDs.TLD ) + 2, 100 ) as ReversedPrefix,
      CharIndex( '.', Substring( Reverse( FQDNs.FQDN ), Len( TLDs.TLD ) + 2, 100 ) ) as DotPosition
      from @SampleFQDNs as FQDNs inner join
        @SampleTLDs as TLDs on FQDNs.FQDN like '%.' + TLDs.TLD or FQDNs.FQDN = TLDs.TLD )
  select FQDN, TLD,
    case
      when DotPosition = 0 then FQDN
      else Reverse( Left( ReversedPrefix, DotPosition - 1) ) + '.' + TLD
      end as Result
    from ExtendedFQDNs
    where TLDLenRank = 1;

答案 1 :(得分:1)

以下是我在C#中的表现:

string getBaseDomain(string fqdn, string suffix)
{
    string[] domainSegs = fqdn.Split('.');
    return domainSegs[domainSegs.Length - suffix.Split('.').Length - 1] + "." + suffix;
}

所以这里是Powershell:

function getBaseDomain
{
  Param(
    [string]$fqdn, 
    [string]$suffix 
  )
  $domainSegs = $fqdn.Split(".");
  return $domainSegs[$domainSegs.Length - $suffix.Split(".").Length - 1] + "."+$suffix;
}

现在看起来相当愚蠢,浪费了stackoverflow.com的时间。道歉。

答案 2 :(得分:1)

这是一个tsql变种......

declare @fqdn varchar(256) = 'somedomain.com'
declare @suffix varchar(128) = 'com'

select left(@fqdn,CHARINDEX(@suffix,@fqdn) - 2)

if(select CHARINDEX('.',reverse(left(@fqdn,CHARINDEX(@suffix,@fqdn) - 2)))) = 0
    begin
    select left(@fqdn,CHARINDEX(@suffix,@fqdn) - 2) + '.' + @suffix
    end
else
    begin
    select right(left(@fqdn,CHARINDEX(@suffix,@fqdn) - 2),CHARINDEX('.',reverse(left(@fqdn,CHARINDEX(@suffix,@fqdn) - 2))) - 1) + '.' + @suffix
    end