System.Net.IPAddress.Parse误将IPv6字符串转为IPv4映射地址问题咨询
你遇到的是IPAddress.ToString()默认格式化规则的问题,和解析逻辑无关,Parse方法对IPv6地址的解析结果完全正确,只是输出时默认对IPv4映射型IPv6地址采用了混合格式,对应的解决方案如下:
方案1:使用.NET内置方法(适用于.NET 5+、.NET Core 3.0+)
高版本.NET已经提供了对应的重载,直接调用带useIpv4Mapping参数的ToString方法即可:
var ip = IPAddress.Parse("::ffff:0808:0808"); // 传入false禁用混合格式输出,保留纯冒号分隔的IPv6格式 string expectedResult = ip.ToString(useIpv4Mapping: false);
执行后expectedResult的值为::ffff:808:808,完全符合需求。
方案2:自定义扩展方法(兼容所有.NET版本,包括.NET Framework)
如果项目需要兼容低版本.NET,可以自己实现格式化逻辑,不需要复杂的字符串处理:
using System; using System.Linq; using System.Net; using System.Net.Sockets; public static class IPAddressExtensions { public static string ToPureIPv6String(this IPAddress ipAddress) { // 非IPv6地址直接返回默认格式 if (ipAddress.AddressFamily != AddressFamily.InterNetworkV6) { return ipAddress.ToString(); } byte[] addressBytes = ipAddress.GetAddressBytes(); // 把16个字节拆分为8个十六进制段 string[] segments = new string[8]; for (int i = 0; i < 8; i++) { segments[i] = $"{addressBytes[i*2]:x}{addressBytes[i*2 + 1]:x}".TrimStart('0'); // 全零段保留一个0 if (string.IsNullOrEmpty(segments[i])) { segments[i] = "0"; } } // 找到最长的连续零段替换为:: int maxZeroLength = 0; int maxZeroStart = -1; int currentZeroLength = 0; int currentZeroStart = -1; for (int i = 0; i < segments.Length; i++) { if (segments[i] == "0") { if (currentZeroStart == -1) { currentZeroStart = i; } currentZeroLength++; if (currentZeroLength > maxZeroLength) { maxZeroLength = currentZeroLength; maxZeroStart = currentZeroStart; } } else { currentZeroStart = -1; currentZeroLength = 0; } } // 连续零段长度≥2才压缩 if (maxZeroLength >= 2) { return string.Join(":", segments.Take(maxZeroStart)) + "::" + string.Join(":", segments.Skip(maxZeroStart + maxZeroLength)).TrimStart(':'); } return string.Join(":", segments); } }
调用方式:
var ip = IPAddress.Parse("::ffff:0808:0808"); string expectedResult = ip.ToPureIPv6String();
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

