gpt4 book ai didi

c# - 如何判断IPv6地址是否私有(private)?

转载 作者:行者123 更新时间:2023-11-30 16:50:13 25 4
gpt4 key购买 nike

我试图确定给定的 IPv6 地址在 C# 中是否私有(private),我很想简单地使用 IPAddress 类上的“IsIPv6SiteLocal”属性。但是,如本 comment 中所述,此属性中实现的逻辑已弃用。我运行了以下单元测试:

[TestMethod]
public void IsPrivate_ipv6_True()
{
// This sample private IPv6 address was generated using: http://unique-local-ipv6.com/
var ip = IPAddress.Parse("fd44:fda4:e1ba::1");
Assert.IsTrue(ip.IsIPv6SiteLocal);
}

单元测试中的断言失败,确认 IsIPv6SiteLocal 未正确确定地址是否为本地地址。所以我需要一个替代方案。

我编写了以下扩展方法,我想知道是否有人能想到无法正确确定地址是私有(private)/公共(public)地址的场景。

public static bool IsPrivateIPv6(this IPAddress address)
{
var addressAsString = address.ToString();
var firstWord = addressAsString.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0];

// Make sure we are dealing with an IPv6 address
if (address.AddressFamily != AddressFamily.InterNetworkV6) return false;

// The original IPv6 Site Local addresses (fec0::/10) are deprecated. Unfortunately IsIPv6SiteLocal only checks for the original deprecated version:
else if (address.IsIPv6SiteLocal) return true;

// These days Unique Local Addresses (ULA) are used in place of Site Local.
// ULA has two variants:
// fc00::/8 is not defined yet, but might be used in the future for internal-use addresses that are registered in a central place (ULA Central).
// fd00::/8 is in use and does not have to registered anywhere.
else if (firstWord.Substring(0, 2) == "fc" && firstWord.Length >= 4) return true;
else if (firstWord.Substring(0, 2) == "fd" && firstWord.Length >= 4) return true;

// Link local addresses (prefixed with fe80) are not routable
else if (firstWord == "fe80") return true;

// Discard Prefix
else if (firstWord == "100") return true;

// Any other IP address is not Unique Local Address (ULA)
else return false;
}

2016 年 2 月 13 日编辑:

  • 确保第一个单词至少有 4 个字符,如@RonMaupin 所建议的
  • 按照@RonMaupin 的建议改进了“else return false”上面的注释
  • 按照@KevinBurdett 的建议检查“fe80”前缀
  • 按照@KevinBurdett 的建议检查“丢弃”前缀

最佳答案

通过为 ::1 添加一个特例并避免他的解决方案中的 ArgumentException(这将在 Substring() 调用中发生)改进了@​​desautelsj 的回答:

public static bool IsPrivateIPv6(IPAddress address)
{
// Make sure we are dealing with an IPv6 address
if (address.AddressFamily != AddressFamily.InterNetworkV6)
throw new ArgumentException("IP address is not V6", "address");

var addressAsString = address.ToString();
var firstWord = addressAsString.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0];

// equivalent of 127.0.0.1 in IPv6
if (addressAsString == "::1")
return true;

// The original IPv6 Site Local addresses (fec0::/10) are deprecated. Unfortunately IsIPv6SiteLocal only checks for the original deprecated version:
else if (address.IsIPv6SiteLocal)
return true;

// These days Unique Local Addresses (ULA) are used in place of Site Local.
// ULA has two variants:
// fc00::/8 is not defined yet, but might be used in the future for internal-use addresses that are registered in a central place (ULA Central).
// fd00::/8 is in use and does not have to registered anywhere.
else if (firstWord.Length >= 4 && firstWord.Substring(0, 2) == "fc")
return true;
else if (firstWord.Length >= 4 && firstWord.Substring(0, 2) == "fd")
return true;

// Link local addresses (prefixed with fe80) are not routable
else if (firstWord == "fe80")
return true;

// Discard Prefix
else if (firstWord == "100")
return true;

// Any other IP address is not Unique Local Address (ULA)
return false;
}

在 F# 中:

let private IsIpv6AddressPrivate (address: IPAddress) =
if address.AddressFamily = AddressFamily.InterNetwork then
invalidArg "address" "address must be IPv6"

// The original IPv6 Site Local addresses (fec0::/10) are deprecated. Unfortunately IsIPv6SiteLocal only checks for the original deprecated version:
elif address.IsIPv6SiteLocal then
true
else
let addressAsString = address.ToString()

// equivalent of 127.0.0.1 in IPv6
if addressAsString = "::1" then
true
else
let firstWord = addressAsString.Split([|':'|], StringSplitOptions.RemoveEmptyEntries).[0]
// These days Unique Local Addresses (ULA) are used in place of Site Local.
// ULA has two variants:
// fc00::/8 is not defined yet, but might be used in the future for internal-use addresses that are registered in a central place (ULA Central).
// fd00::/8 is in use and does not have to registered anywhere.
if (firstWord.Length >= 4 && firstWord.Substring(0, 2) = "fc") ||
(firstWord.Length >= 4 && firstWord.Substring(0, 2) = "fd") ||
// Link local addresses (prefixed with fe80) are not routable
(firstWord = "fe80") ||
// Discard Prefix
(firstWord = "100") then
true
else
false

关于c# - 如何判断IPv6地址是否私有(private)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35374207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com