github.com/searKing/golang/go@v1.2.117/net/ip.go (about) 1 // Copyright 2021 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package net 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "math/big" 11 "net" 12 ) 13 14 // INetAToN returns the numeric value of an IP address 15 var INetAToN = IP4toUInt32 16 17 // INetNToA returns the IP address from a numeric value 18 var INetNToA = ParseIPV4 19 20 // INet6AToN returns the numeric value of an IPv6 address 21 var INet6AToN = IPtoBigInt 22 23 // INet6NToA returns the IPv6 address from a numeric value 24 var INet6NToA = ParseIPV6 25 26 type IPFormat net.IP 27 28 func (ip IPFormat) Format(s fmt.State, verb rune) { 29 switch verb { 30 case 'b', 'o', 'O', 'd', 'x', 'X': 31 IPtoBigInt(net.IP(ip)).Format(s, verb) 32 return 33 default: 34 _, _ = fmt.Fprintf(s, "%"+string(verb), net.IP(ip)) 35 } 36 } 37 38 // ParseIPV4 parses i as an IP address, returning the result. 39 // If i is not a valid integer representation of an IP address, 40 // ParseIP returns nil. 41 func ParseIPV4(i uint32) net.IP { 42 ip := make(net.IP, net.IPv4len) 43 binary.BigEndian.PutUint32(ip, i) 44 return ip.To4() 45 } 46 47 func ParseIPV6(s string, base int) net.IP { 48 ipi, ok := big.NewInt(0).SetString(s, base) 49 if !ok { 50 return nil 51 } 52 ipb := ipi.Bytes() 53 if len(ipb) == net.IPv4len { 54 return net.ParseIP(net.IP(ipb).To4().String()) 55 } 56 57 ip := make(net.IP, net.IPv6len) 58 for i := 0; i < len(ip); i++ { 59 j := len(ip) - 1 - i 60 k := len(ipb) - 1 - i 61 if k < 0 { 62 break 63 } 64 ip[j] = ipb[k] 65 } 66 return ip.To16() 67 } 68 69 func ParseIP(s string) net.IP { 70 return ParseIPV6(s, 10) 71 } 72 73 func IPtoBigInt(ip net.IP) *big.Int { 74 ipInt := big.NewInt(0) 75 // If IPv4, use dotted notation. 76 if p4 := ip.To4(); len(p4) == net.IPv4len { 77 ip = ip.To4() 78 } else { 79 ip = ip.To16() 80 } 81 ipInt.SetBytes(ip) 82 return ipInt 83 } 84 85 func IP4toUInt32(ip net.IP) uint32 { 86 ipInt := big.NewInt(0) 87 // If IPv4, use dotted notation. 88 if p4 := ip.To4(); len(p4) == net.IPv4len { 89 ip = ip.To4() 90 } else { 91 return 0 92 } 93 ipInt.SetBytes(ip) 94 return uint32(ipInt.Uint64()) 95 }