golang 获取公网ip 内网ip 检测ip类型 校验ip区间 ip地址string和int转换 判断ip地区国家运营商
目錄
簡要簡介net包
什么是外網IP和內網IP?
獲取公網ip
獲取本地ip
判斷是否是公網ip
ip地址string轉int
ip地址int轉string
判斷ip地址區間
通過淘寶接口根據公網ip獲取國家運營商等信息
完整代碼
簡要簡介net包
func ParseIP
func ParseIP(s string) IP
ParseIP parses s as an IP address, returning the result. The string s can be in dotted decimal (“192.0.2.1”) or IPv6 (“2001:db8::68”) form. If s is not a valid textual representation of an IP address, ParseIP returns nil.
ParseIP將s解析為IP地址,并返回結果。 字符串s可以是點分十進制(“ 192.0.2.1”)或IPv6(“ 2001:db8 :: 68”)形式。 如果s不是IP地址的有效文本表示形式,則ParseIP返回nil。
func InterfaceAddrs
func InterfaceAddrs() ([]Addr, error)
InterfaceAddrs returns a list of the system’s unicast interface addresses.
InterfaceAddrs返回系統的單播接口地址的列表。
The returned list does not identify the associated interface; use Interfaces and Interface.Addrs for more detail.
返回的列表不標識關聯的接口; 有關更多詳細信息,請使用Interfaces和Interface.Addrs。
type IPNet
An IPNet represents an IP network.
type IPNet struct { IP IP // network number Mask IPMask // network mask }
type IP
An IP is a single IP address, a slice of bytes. Functions in this package accept either 4-byte (IPv4) or 16-byte (IPv6) slices as input.
IP是單個IP??地址,是字節的一部分。 此程序包中的功能接受4字節(IPv4)或16字節(IPv6)切片作為輸入。
Note that in this documentation, referring to an IP address as an IPv4 address or an IPv6 address is a semantic property of the address, not just the length of the byte slice: a 16-byte slice can still be an IPv4 address.
請注意,在本文檔中,將IP地址稱為IPv4地址或IPv6地址是該地址的語義屬性,而不僅僅是字節片的長度:16字節片仍然可以是IPv4地址。
type IP []byte
func IPv4
func IPv4(a, b, c, d byte) IP
IPv4 returns the IP address (in 16-byte form) of the IPv4 address a.b.c.d.
點到為止,更詳細的請看文檔:https://golang.org/pkg/net
什么是外網IP和內網IP?
tcp/ip協議中,專門保留了三個IP地址區域作為私有地址,其地址范圍如下:
10.0.0.0/8:10.0.0.0~10.255.255.255
172.16.0.0/12:172.16.0.0~172.31.255.255
192.168.0.0/16:192.168.0.0~192.168.255.255
什么是內網IP
一些小型企業或者學校,通常都是申請一個固定的IP地址,然后通過IP共享(IP Sharing),使用整個公司或學校的機器都能夠訪問互聯網。而這些企業或學校的機器使用的IP地址就是內網IP,內網IP是在規劃IPv4協議時,考慮到IP地址資源可能不足,就專門為內部網設計私有IP地址(或稱之為保留地址),一般常用內網IP地址都是這種形式的:10.X.X.X、172.16.X.X-172.31.X.X、192.168.X.X等。需要注意的是,內網的計算機可向Internet上的其他計算機發送連接請求,但Internet上其他的計算機無法向內網的計算機發送連接請求。我們平時可能在內網機器上搭建過網站或者FTP服務器,而在外網是不能訪問該網站和FTP服務器的,原因就在于此。
什么是公網IP
公網IP就是除了保留IP地址以外的IP地址,可以與Internet上的其他計算機隨意互相訪問。我們通常所說的IP地址,其實就是指的公網IP?;ヂ摼W上的每臺計算機都有一個獨立的IP地址,該IP地址唯一確定互聯網上的一臺計算機。這里的IP地址就是指的公網IP地址。
怎樣理解互聯網上的每臺計算機都有一個唯一的IP地址
其實,互聯網上的計算機是通過“公網IP+內網IP”來唯一確定的,就像很多大樓都是201房間一樣,房間號可能一樣,但是大樓肯定是唯一的。公網IP地址和內網IP地址也是同樣,不同企業或學校的機器可能有相同的內網IP地址,但是他們的公網IP地址肯定不同。那么這些企業或學校的計算機是怎樣IP地址共享的呢?這就需要使用NAT(Network Address Translation,網絡地址轉換)功能。當內部計算機要連接互聯網時,首先需要通過NAT技術,將內部計算機數據包中有關IP地址的設置都設成NAT主機的公共IP地址,然后再傳送到Internet,雖然內部計算機使用的是私有IP地址,但在連接Internet時,就可以通過NAT主機的NAT技術,將內網我IP地址修改為公網IP地址,如此一來,內網計算機就可以向Internet請求數據了。
獲取公網ip
百度ip,即可查看公網ip
curl命令查看公網ip
curl ipinfo.io/ip
通過http://myexternalip.com/raw獲取公網ip
func get_external() string {resp, err := http.Get("http://myexternalip.com/raw")if err != nil {return ""}defer resp.Body.Close()content, _ := ioutil.ReadAll(resp.Body)//buf := new(bytes.Buffer)//buf.ReadFrom(resp.Body)//s := buf.String()return string(content)
}
獲取本地ip
func GetIntranetIp() {addrs, err := net.InterfaceAddrs()if err != nil {fmt.Println(err)os.Exit(1)}for _, address := range addrs {// 檢查ip地址判斷是否回環地址if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {if ipnet.IP.To4() != nil {fmt.Println("ip:", ipnet.IP.String())}}}
}
通過dns服務器8.8.8.8:80獲取使用的ip
func GetPulicIP() string {conn, _ := net.Dial("udp", "8.8.8.8:80")defer conn.Close()localAddr := conn.LocalAddr().String()idx := strings.LastIndex(localAddr, ":")return localAddr[0:idx]
}
判斷是否是公網ip
func IsPublicIP(IP net.IP) bool {if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {return false}if ip4 := IP.To4(); ip4 != nil {switch true {case ip4[0] == 10:return falsecase ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:return falsecase ip4[0] == 192 && ip4[1] == 168:return falsedefault:return true}}return false
}
ip地址string轉int
func inet_aton(ipnr net.IP) int64 {bits := strings.Split(ipnr.String(), ".")b0, _ := strconv.Atoi(bits[0])b1, _ := strconv.Atoi(bits[1])b2, _ := strconv.Atoi(bits[2])b3, _ := strconv.Atoi(bits[3])var sum int64sum += int64(b0) << 24sum += int64(b1) << 16sum += int64(b2) << 8sum += int64(b3)return sum
}
ip地址int轉string
func inet_ntoa(ipnr int64) net.IP {var bytes [4]bytebytes[0] = byte(ipnr & 0xFF)bytes[1] = byte((ipnr >> 8) & 0xFF)bytes[2] = byte((ipnr >> 16) & 0xFF)bytes[3] = byte((ipnr >> 24) & 0xFF)return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0])
}
判斷ip地址區間
func IpBetween(from net.IP, to net.IP, test net.IP) bool {if from == nil || to == nil || test == nil {fmt.Println("An ip input is nil") // or return an error!?return false}from16 := from.To16()to16 := to.To16()test16 := test.To16()if from16 == nil || to16 == nil || test16 == nil {fmt.Println("An ip did not convert to a 16 byte") // or return an error!?return false}if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {return true}return false
}
通過淘寶接口根據公網ip獲取國家運營商等信息
接口:
http://ip.taobao.com/service/getIpInfo.php?ip=
type IPInfo struct {Code int `json:"code"`Data IP `json:"data`
}type IP struct {Country string `json:"country"`CountryId string `json:"country_id"`Area string `json:"area"`AreaId string `json:"area_id"`Region string `json:"region"`RegionId string `json:"region_id"`City string `json:"city"`CityId string `json:"city_id"`Isp string `json:"isp"`
}func TabaoAPI(ip string) *IPInfo {url := "http://ip.taobao.com/service/getIpInfo.php?ip="url += ipresp, err := http.Get(url)if err != nil {return nil}defer resp.Body.Close()out, err := ioutil.ReadAll(resp.Body)if err != nil {return nil}var result IPInfoif err := json.Unmarshal(out, &result); err != nil {return nil}return &result
}
完整代碼
package mainimport ("bytes""encoding/json""fmt""io/ioutil""net""net/http""os""strconv""strings"
)type IPInfo struct {Code int `json:"code"`Data IP `json:"data`
}type IP struct {Country string `json:"country"`CountryId string `json:"country_id"`Area string `json:"area"`AreaId string `json:"area_id"`Region string `json:"region"`RegionId string `json:"region_id"`City string `json:"city"`CityId string `json:"city_id"`Isp string `json:"isp"`
}func main() {external_ip := get_external()external_ip = strings.Replace(external_ip, "\n", "", -1)fmt.Println("公網ip是: ", external_ip)fmt.Println("------Dividing Line------")ip := net.ParseIP(external_ip)if ip == nil {fmt.Println("您輸入的不是有效的IP地址,請重新輸入!")} else {result := TabaoAPI(string(external_ip))if result != nil {fmt.Println("國家:", result.Data.Country)fmt.Println("地區:", result.Data.Area)fmt.Println("城市:", result.Data.City)fmt.Println("運營商:", result.Data.Isp)}}fmt.Println("------Dividing Line------")GetIntranetIp()fmt.Println("------Dividing Line------")ip_int := inet_aton(net.ParseIP(external_ip))fmt.Println("Convert IPv4 address to decimal number(base 10) :", ip_int)ip_result := inet_ntoa(ip_int)fmt.Println("Convert decimal number(base 10) to IPv4 address:", ip_result)fmt.Println("------Dividing Line------")is_between := IpBetween(net.ParseIP("0.0.0.0"), net.ParseIP("255.255.255.255"), net.ParseIP(external_ip))fmt.Println("check result: ", is_between)fmt.Println("------Dividing Line------")is_public_ip := IsPublicIP(net.ParseIP(external_ip))fmt.Println("It is public ip: ", is_public_ip)is_public_ip = IsPublicIP(net.ParseIP("169.254.85.131"))fmt.Println("It is public ip: ", is_public_ip)fmt.Println("------Dividing Line------")fmt.Println(GetPulicIP())
}func get_external() string {resp, err := http.Get("http://myexternalip.com/raw")if err != nil {return ""}defer resp.Body.Close()content, _ := ioutil.ReadAll(resp.Body)buf := new(bytes.Buffer)buf.ReadFrom(resp.Body)//s := buf.String()return string(content)
}func GetIntranetIp() {addrs, err := net.InterfaceAddrs()if err != nil {fmt.Println(err)os.Exit(1)}for _, address := range addrs {// 檢查ip地址判斷是否回環地址if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {if ipnet.IP.To4() != nil {fmt.Println("ip:", ipnet.IP.String())}}}
}func TabaoAPI(ip string) *IPInfo {url := "http://ip.taobao.com/service/getIpInfo.php?ip="url += ipresp, err := http.Get(url)if err != nil {return nil}defer resp.Body.Close()out, err := ioutil.ReadAll(resp.Body)if err != nil {return nil}var result IPInfoif err := json.Unmarshal(out, &result); err != nil {return nil}return &result
}func inet_ntoa(ipnr int64) net.IP {var bytes [4]bytebytes[0] = byte(ipnr & 0xFF)bytes[1] = byte((ipnr >> 8) & 0xFF)bytes[2] = byte((ipnr >> 16) & 0xFF)bytes[3] = byte((ipnr >> 24) & 0xFF)return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0])
}func inet_aton(ipnr net.IP) int64 {bits := strings.Split(ipnr.String(), ".")b0, _ := strconv.Atoi(bits[0])b1, _ := strconv.Atoi(bits[1])b2, _ := strconv.Atoi(bits[2])b3, _ := strconv.Atoi(bits[3])var sum int64sum += int64(b0) << 24sum += int64(b1) << 16sum += int64(b2) << 8sum += int64(b3)return sum
}func IpBetween(from net.IP, to net.IP, test net.IP) bool {if from == nil || to == nil || test == nil {fmt.Println("An ip input is nil") // or return an error!?return false}from16 := from.To16()to16 := to.To16()test16 := test.To16()if from16 == nil || to16 == nil || test16 == nil {fmt.Println("An ip did not convert to a 16 byte") // or return an error!?return false}if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {return true}return false
}func IsPublicIP(IP net.IP) bool {if IP.IsLoopback() || IP.IsLinkLocalMulticast() || IP.IsLinkLocalUnicast() {return false}if ip4 := IP.To4(); ip4 != nil {switch true {case ip4[0] == 10:return falsecase ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31:return falsecase ip4[0] == 192 && ip4[1] == 168:return falsedefault:return true}}return false
}func GetPulicIP() string {conn, _ := net.Dial("udp", "8.8.8.8:80")defer conn.Close()localAddr := conn.LocalAddr().String()idx := strings.LastIndex(localAddr, ":")return localAddr[0:idx]
}
輸出:
公網ip是: 222.128.17*.***
------Dividing Line------
國家: 中國
地區: 華北
城市: 北京市
運營商: 聯通
------Dividing Line------
ip: 169.254.85.131
ip: 169.254.64.29
ip: 169.254.211.178
ip: 192.168.106.1
ip: 192.168.154.1
ip: 169.254.212.223
ip: 192.168.10.26
ip: 169.254.63.20
------Dividing Line------
Convert IPv4 address to decimal number(base 10) : 373297****
Convert decimal number(base 10) to IPv4 address: 222.128.17*.***
------Dividing Line------
check result: true
------Dividing Line------
It is public ip: true
It is public ip: false
------Dividing Line------
192.168.10.26
?
?
?
總結
以上是生活随笔為你收集整理的golang 获取公网ip 内网ip 检测ip类型 校验ip区间 ip地址string和int转换 判断ip地区国家运营商的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客题霸 [ 旋转数组] C++题解/答
- 下一篇: Dynamics 365 FO学习笔记