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  }