note.wcoder.com
wcoder GitHub

127.0.0.1 —> 127.255.255.254(去掉0和255) 的范围都是本地环回地址/回环地址
RFC 1122:互联网标准文档 RFC 1122 规定,IP 地址 127.0.0.1 用于表示本地主机(localhost)。这个地址范围 127.0.0.0/8(即 127.0.0.0 到 127.255.255.255)都被预留用于本地回环通信。
需要注意的是,环回地址范围内不包含的两个IP:127.0.0.0 和 127.255.255.255。
原因很简单:主机号全0代表「网络地址」,全1代表「广播地址」。

package main

import (
	"fmt"
	"math/big"
	"net"
	"strings"
)

// IPPair 存储IP对
type IPPair struct {
	IPv6 net.IP
	IPv4 net.IP
}

// IPConverter IP地址转换器
type IPConverter struct {
	upperCase bool
}

// NewIPConverter 创建新的转换器
func NewIPConverter(upperCase bool) *IPConverter {
	return &IPConverter{
		upperCase: upperCase,
	}
}

// ToBase36 将IPv6和IPv4组合转换为36进制
func (c *IPConverter) ToBase36(ipv6, ipv4 string) (string, error) {
	// 解析IPv6
	var ip6 net.IP
	if ipv6 != "" {
		ip6 = net.ParseIP(ipv6)
		if ip6 != nil && ip6.To4() != nil {
			return "", fmt.Errorf("invalid IPv6 address: %s", ipv6)
		}
	}

	// 解析IPv4
	var ip4 net.IP
	if ipv4 != "" {
		ip4 = net.ParseIP(ipv4)
		if ip4 == nil || ip4.To4() == nil {
			return "", fmt.Errorf("invalid IPv4 address: %s", ipv4)
		}
		ip4 = ip4.To4()
	}

	if ip6 == nil && ip4 == nil {
		return "", fmt.Errorf("no valid IP address provided")
	}

	// 创建大整数存储组合结果
	result := new(big.Int)

	if ip6 != nil {
		// 存储IPv6(如果有)
		result.SetBytes(ip6.To16())
		// 左移32位,为IPv4预留空间
		result.Lsh(result, 32)
	}

	if ip4 != nil {
		// 将IPv4添加到结果中
		ipv4Int := new(big.Int).SetBytes(ip4)
		result.Or(result, ipv4Int)
	}

	// 转换为36进制
	base36 := result.Text(36)
	if c.upperCase {
		base36 = strings.ToUpper(base36)
	}

	return base36, nil
}

// FromBase36 从36进制解析回IPv6和IPv4
func (c *IPConverter) FromBase36(s string) (*IPPair, error) {
	// 解析36进制字符串
	ipInt := new(big.Int)
	_, ok := ipInt.SetString(s, 36)
	if !ok {
		return nil, fmt.Errorf("invalid base36 string: %s", s)
	}

	// 创建返回结果
	pair := &IPPair{}

	// 提取IPv4部分(最后32位)
	ipv4Int := new(big.Int).And(ipInt, new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 32), big.NewInt(1)))
	if ipv4Int.BitLen() > 0 {
		ipv4Bytes := ipv4Int.Bytes()
		pair.IPv4 = make(net.IP, 4)
		copy(pair.IPv4[4-len(ipv4Bytes):], ipv4Bytes)
	}

	// 提取IPv6部分(去除最后32位)
	ipv6Int := new(big.Int).Rsh(ipInt, 32)
	if ipv6Int.BitLen() > 0 {
		ipv6Bytes := ipv6Int.Bytes()
		if len(ipv6Bytes) > 0 {
			pair.IPv6 = make(net.IP, 16)
			copy(pair.IPv6[16-len(ipv6Bytes):], ipv6Bytes)
		}
	}

	return pair, nil
}

func main() {
	converter := NewIPConverter(false)

	// 测试场景
	testCases := []struct {
		name string
		ipv6 string
		ipv4 string
	}{
		{
			name: "IPv6 + IPv4",
			ipv6: "2001:db8::1",
			ipv4: "192.168.1.1",
		},
		{
			name: "只有IPv4",
			ipv6: "",
			ipv4: "192.168.1.1",
		},
		{
			name: "只有IPv6",
			ipv6: "2001:db8::1",
			ipv4: "",
		},
		{
			name: "特殊地址组合",
			ipv6: "fe80::1",
			ipv4: "127.0.0.1",
		},
		{
			name: "最大值组合",
			ipv6: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
			ipv4: "255.255.255.255",
		},
	}

	for _, tc := range testCases {
		fmt.Printf("\n测试场景: %s\n", tc.name)
		fmt.Printf("原始 IPv6: %s\n", tc.ipv6)
		fmt.Printf("原始 IPv4: %s\n", tc.ipv4)

		// 转换为36进制
		base36, err := converter.ToBase36(tc.ipv6, tc.ipv4)
		if err != nil {
			fmt.Printf("转换错误: %v\n", err)
			continue
		}
		fmt.Printf("Base36: %s\n", base36)

		// 转换回IP对
		pair, err := converter.FromBase36(base36)
		if err != nil {
			fmt.Printf("反向转换错误: %v\n", err)
			continue
		}

		fmt.Printf("解析后 IPv6: %s\n", pair.IPv6)
		fmt.Printf("解析后 IPv4: %s\n", pair.IPv4)

		// 验证结果
		if tc.ipv6 != "" && pair.IPv6.String() != net.ParseIP(tc.ipv6).String() {
			fmt.Printf("警告: IPv6不匹配!\n")
		}
		if tc.ipv4 != "" && pair.IPv4.String() != net.ParseIP(tc.ipv4).String() {
			fmt.Printf("警告: IPv4不匹配!\n")
		}
	}
}

校验

package main

import (
	"fmt"
	"math/big"
	"net"
	"strings"
)

// IPPair 存储IP对
type IPPair struct {
	IPv6 net.IP
	IPv4 net.IP
}

// IPConverter IP地址转换器
type IPConverter struct {
	upperCase bool
	maxIPv6   *big.Int // IPv6最大值 (2^128 - 1)
	maxIPv4   *big.Int // IPv4最大值 (2^32 - 1)
}

// NewIPConverter 创建新的转换器
func NewIPConverter(upperCase bool) *IPConverter {
	// 计算IPv6最大值 (2^128 - 1)
	maxIPv6 := new(big.Int).Lsh(big.NewInt(1), 128)
	maxIPv6.Sub(maxIPv6, big.NewInt(1))

	// 计算IPv4最大值 (2^32 - 1)
	maxIPv4 := new(big.Int).Lsh(big.NewInt(1), 32)
	maxIPv4.Sub(maxIPv4, big.NewInt(1))

	return &IPConverter{
		upperCase: upperCase,
		maxIPv6:   maxIPv6,
		maxIPv4:   maxIPv4,
	}
}

// validateIPv4 验证IPv4地址
func validateIPv4(ip string) (net.IP, error) {
	if ip == "" {
		return nil, nil
	}

	parsed := net.ParseIP(ip)
	if parsed == nil {
		return nil, fmt.Errorf("invalid IPv4 address: %s", ip)
	}

	ipv4 := parsed.To4()
	if ipv4 == nil {
		return nil, fmt.Errorf("not an IPv4 address: %s", ip)
	}

	return ipv4, nil
}

// validateIPv6 验证IPv6地址
func validateIPv6(ip string) (net.IP, error) {
	if ip == "" {
		return nil, nil
	}

	parsed := net.ParseIP(ip)
	if parsed == nil {
		return nil, fmt.Errorf("invalid IPv6 address: %s", ip)
	}

	if parsed.To4() != nil {
		return nil, fmt.Errorf("not an IPv6 address: %s", ip)
	}

	return parsed.To16(), nil
}

// ToBase36 将IPv6和IPv4组合转换为36进制
func (c *IPConverter) ToBase36(ipv6, ipv4 string) (string, error) {
	// 验证IP地址
	ip6, err := validateIPv6(ipv6)
	if err != nil {
		return "", err
	}

	ip4, err := validateIPv4(ipv4)
	if err != nil {
		return "", err
	}

	if ip6 == nil && ip4 == nil {
		return "", fmt.Errorf("at least one IP address must be provided")
	}

	// 创建大整数存储组合结果
	result := new(big.Int)

	if ip6 != nil {
		// 存储IPv6
		ipv6Int := new(big.Int).SetBytes(ip6)
		// 验证IPv6不超过最大值
		if ipv6Int.Cmp(c.maxIPv6) > 0 {
			return "", fmt.Errorf("IPv6 value exceeds maximum")
		}
		result.Set(ipv6Int)
		// 左移32位,为IPv4预留空间
		result.Lsh(result, 32)
	}

	if ip4 != nil {
		// 验证IPv4不超过最大值
		ipv4Int := new(big.Int).SetBytes(ip4)
		if ipv4Int.Cmp(c.maxIPv4) > 0 {
			return "", fmt.Errorf("IPv4 value exceeds maximum")
		}
		// 将IPv4添加到结果中
		result.Or(result, ipv4Int)
	}

	// 转换为36进制
	base36 := result.Text(36)
	if c.upperCase {
		base36 = strings.ToUpper(base36)
	}

	return base36, nil
}

// FromBase36 从36进制解析回IPv6和IPv4
func (c *IPConverter) FromBase36(s string) (*IPPair, error) {
	// 解析36进制字符串
	ipInt := new(big.Int)
	_, ok := ipInt.SetString(s, 36)
	if !ok {
		return nil, fmt.Errorf("invalid base36 string: %s", s)
	}

	// 验证总值不超过最大允许值
	maxCombined := new(big.Int).Set(c.maxIPv6)
	maxCombined.Lsh(maxCombined, 32)
	maxCombined.Or(maxCombined, c.maxIPv4)

	if ipInt.Cmp(maxCombined) > 0 {
		return nil, fmt.Errorf("combined value exceeds maximum allowed")
	}

	// 创建返回结果
	pair := &IPPair{}

	// 提取IPv4部分(最后32位)
	ipv4Int := new(big.Int).And(ipInt, c.maxIPv4)
	if ipv4Int.BitLen() > 0 {
		// 验证IPv4值
		if ipv4Int.Cmp(c.maxIPv4) > 0 {
			return nil, fmt.Errorf("IPv4 portion exceeds maximum")
		}
		ipv4Bytes := ipv4Int.Bytes()
		pair.IPv4 = make(net.IP, 4)
		copy(pair.IPv4[4-len(ipv4Bytes):], ipv4Bytes)
	}

	// 提取IPv6部分(去除最后32位)
	ipv6Int := new(big.Int).Rsh(ipInt, 32)
	if ipv6Int.BitLen() > 0 {
		// 验证IPv6值
		if ipv6Int.Cmp(c.maxIPv6) > 0 {
			return nil, fmt.Errorf("IPv6 portion exceeds maximum")
		}
		ipv6Bytes := ipv6Int.Bytes()
		if len(ipv6Bytes) > 0 {
			pair.IPv6 = make(net.IP, 16)
			copy(pair.IPv6[16-len(ipv6Bytes):], ipv6Bytes)
		}
	}

	return pair, nil
}

func main() {
	converter := NewIPConverter(false)

	// 测试场景
	testCases := []struct {
		name string
		ipv6 string
		ipv4 string
	}{
		{
			name: "IPv6 + IPv4",
			ipv6: "2001:db8::1",
			ipv4: "192.168.1.1",
		},
		{
			name: "只有IPv4",
			ipv6: "",
			ipv4: "192.168.1.1",
		},
		{
			name: "只有IPv6",
			ipv6: "2001:db8::1",
			ipv4: "",
		},
		{
			name: "最大值测试",
			ipv6: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
			ipv4: "255.255.255.255",
		},
	}

	for _, tc := range testCases {
		fmt.Printf("\n测试场景: %s\n", tc.name)
		fmt.Printf("原始 IPv6: %s\n", tc.ipv6)
		fmt.Printf("原始 IPv4: %s\n", tc.ipv4)

		// 转换为36进制
		base36, err := converter.ToBase36(tc.ipv6, tc.ipv4)
		if err != nil {
			fmt.Printf("转换错误: %v\n", err)
			continue
		}
		fmt.Printf("Base36: %s\n", base36)

		// 转换回IP对
		pair, err := converter.FromBase36(base36)
		if err != nil {
			fmt.Printf("反向转换错误: %v\n", err)
			continue
		}

		fmt.Printf("解析后 IPv6: %s\n", pair.IPv6)
		fmt.Printf("解析后 IPv4: %s\n", pair.IPv4)

		// 验证结果
		if tc.ipv6 != "" && pair.IPv6.String() != net.ParseIP(tc.ipv6).String() {
			fmt.Printf("警告: IPv6不匹配!\n")
		}
		if tc.ipv4 != "" && pair.IPv4.String() != net.ParseIP(tc.ipv4).String() {
			fmt.Printf("警告: IPv4不匹配!\n")
		}
		fmt.Printf("----------\n")
	}
}


检查IPv4

// IPv4Checker IPv4地址检查器
type IPv4Checker struct {
    privateIPRanges []*net.IPNet
}

// NewIPv4Checker 创建新的IPv4检查器
func NewIPv4Checker() *IPv4Checker {
    checker := &IPv4Checker{}
    // 初始化内网IP范围
    privateRanges := []string{
        "10.0.0.0/8",     // RFC1918
        "172.16.0.0/12",  // RFC1918
        "192.168.0.0/16", // RFC1918
        "169.254.0.0/16", // RFC3927 Link-Local
        "127.0.0.0/8",    // RFC1122 Loopback
        "100.64.0.0/10",  // RFC6598 Shared Address Space
        "192.0.0.0/24",   // RFC6890
        "192.0.2.0/24",   // RFC5737 TEST-NET-1
        "198.18.0.0/15",  // RFC2544 Benchmark
        "198.51.100.0/24",// RFC5737 TEST-NET-2
        "203.0.113.0/24", // RFC5737 TEST-NET-3
        "224.0.0.0/4",    // RFC5771 Multicast
        "240.0.0.0/4",    // RFC1112 Reserved
    }
    
    for _, cidr := range privateRanges {
        _, network, _ := net.ParseCIDR(cidr)
        if network != nil {
            checker.privateIPRanges = append(checker.privateIPRanges, network)
        }
    }
    return checker
}

// IsPrivateIP 判断是否为内网IP
func (c *IPv4Checker) IsPrivateIP(ipStr string) bool {
    ip := net.ParseIP(ipStr)
    if ip == nil {
        return false
    }
    
    // 检查是否在内网范围内
    for _, privateRange := range c.privateIPRanges {
        if privateRange.Contains(ip) {
            return true
        }
    }
    return false
}
// 定义所有内网IPv4网段
	networks := []struct {
		CIDR string
		Type string
	}{
		// RFC 1918 私有网络
		{"10.0.0.0/8", "Private-A"},
		{"172.16.0.0/12", "Private-B"},
		{"192.168.0.0/16", "Private-C"},
		// 回环地址
		{"127.0.0.0/8", "Loopback"},
		// Link-Local
		{"169.254.0.0/16", "Link-Local"},
		// 组播地址
		{"224.0.0.0/4", "Multicast"},
		// 广播地址
		{"255.255.255.255/32", "Broadcast"},
		// 保留地址
		{"0.0.0.0/8", "Reserved"},
		{"100.64.0.0/10", "Shared-Address-Space"},
		{"192.0.0.0/24", "IETF-Protocol"},
		{"192.0.2.0/24", "TEST-NET-1"},
		{"198.18.0.0/15", "Benchmark"},
		{"198.51.100.0/24", "TEST-NET-2"},
		{"203.0.113.0/24", "TEST-NET-3"},
		{"240.0.0.0/4", "Reserved"},
	}


// 定义所有内网IPv6网段
	networks := []struct {
		CIDR string
		Type string
	}{
		// Unique Local Address (ULA)
		{"fc00::/7", "ULA"},
		// Link-Local
		{"fe80::/10", "Link-Local"},
		// Site-Local (已弃用,但仍需检查)
		{"fec0::/10", "Site-Local-Deprecated"},
		// Loopback
		{"::1/128", "Loopback"},
		// 组播地址
		{"ff00::/8", "Multicast"},
		// 本地组播
		{"ff01::/16", "Interface-Local-Multicast"},
		{"ff02::/16", "Link-Local-Multicast"},
		{"ff03::/16", "Realm-Local-Multicast"},
		{"ff04::/16", "Admin-Local-Multicast"},
		{"ff05::/16", "Site-Local-Multicast"},
		// 文档示例地址
		{"2001:db8::/32", "Documentation"},
		// 6to4地址
		{"2002::/16", "6to4"},
		// Teredo隧道
		{"2001::/32", "Teredo"},
		// 保留地址
		{"::/128", "Unspecified"},
		{"100::/64", "Discard-Only"},
		{"64:ff9b::/96", "IPv4-IPv6-Translation"},
	}	
← Previous Next →
Less
More