本篇文章更新時間:2020/06/01
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~


網址資源 https://www.mxp.tw 這樣去拆解出網域(Host: www.mxp.tw)是容易,規則不難,通過字串分割後取得即可。

但要取得「主網域」又或是「裸網域(Naked Domain)」,就複雜許多。

舉例:

  • www.mxp.tw 主網域是 mxp.tw,子網域名稱: www
  • www.google.com.tw 主網域是 google.com.tw,子網域名稱是: www
  • www.abc.uk 主網域是 abc.uk,子網域名稱: www
  • www.abc.co.uk 主網域是 abc.co.uk,子網域名稱: www

看得出來規則嗎? 才怪XD 階層規則其實並無通解。需要透過總表來比對判斷。

總表清單: PUBLIC SUFFIX LIST

PUBLIC SUFFIX LIST

對照列表去做比對求得主網域,才能把這主網域送給 Whois Server 去查詢註冊狀態。

寫 Go 專案來處理的時候一開始使用 tldparser 這款,直到研究下方專案時才發現有一個官方的函式庫就可以處理: golang.org/x/net/publicsuffix

Public Zone Database http://zonedb.org 是 Mozilla 基金會支持的一個開源專案,紀錄公開的網域相關資訊。

程式碼範例如下:

package main

import (
    "fmt"
    "golang.org/x/net/publicsuffix"
    "strings"
    "flag"
    "golang.org/x/net/idna"
)

var (
    name = flag.String("d", "", "Any domain name")
)

func main() {
    flag.Parse()
    if len(*name) == 0 {
        fmt.Println(0,"ERR_INPUT")
        return
    }
    pdn, punnycv_err := idna.Punycode.ToASCII(*name)
    if punnycv_err != nil {
        fmt.Println("Punnycode convert err:",pdn,punnycv_err)
        return
    }
    tld, tld_err := publicsuffix.PublicSuffix(pdn)
    if tld_err != true {
        fmt.Println("TLD err:",tld_err)
        return
    }
    dom, dom_err := publicsuffix.EffectiveTLDPlusOne(pdn)
    if dom_err != nil {
        fmt.Println("Domain err:",dom_err)
        return
    }
    sub := strings.Replace(pdn, "."+dom, "", -1)
    if sub == dom {
        sub = ""
    }
    fmt.Println("子網域名:",sub," 主網域:",dom,"頂級域名:",tld)
}

要注意的是 IDNA 國際化域名/特殊字元域名 要先轉國際化域名編碼(Punycode)後才能對照 TLD 頂級域名表!

上面範例存檔為 main.go 後使用指令: go build main.go 即可編譯出一個執行檔案。(需解決函式庫相依問題)

執行程式: ./main -d www.中文.台灣 會得到輸出:

子網域名: www 主網域: xn--fiq228c.xn--kpry57d 頂級域名: xn--kpry57d


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[//////////____30%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *