我昨天问了一个关于将HEX字符串转换为IP的问题并得到了答案:C# convert hex into ip
当我使用函数
时,问题是var ip = new IPAddress(long.Parse(ipString, NumberStyles.AllowHexSpecifier));
它会返回一个有效的IPAddress,但会以相反的方式执行。例如:
十六进制字符串:
c0a8000a
并且应该解析为:
192.168.0.10
long.Parse()函数返回
3232235530
但是在调用IPAddress构造函数后我的IP是
10.0.168.192
而不是正确的。像http://www.smartconversion.com/unit_conversion/IP_Address_Converter.aspx这样的在线工具运行正常。这是一个有点或大端的东西?我是否必须自己翻转字符串或者是否有更简单的答案?
答案 0 :(得分:2)
所以你做了一点研究,你猜对了。它与字节序有关。
构造函数:IPAddress(long newAddress)期望值在network byte order中,并定义为 big-endian 。
我假设您的系统架构使用 little-endian (正如大多数英特尔系统那样)
.NET
使用底层系统的字节序,因此当您在这样的系统上解析long
时,它会存储为little-endian。
这就是为什么当您通过IPAddress.Parse
解析整数 string 时,结果是正确的。
至于解决方案。
您可以解析IPAddress(按字符串):
IPAddress ip = IPAddress.Parse(uint.Parse(ipString, NumberStyles.AllowHexSpecifier).ToString());
或者为了更加“正确”,您可以检查BitConverter.IsLittleEndian
字段并在nescessery中翻转字节顺序:
static IPAddress ParseHexIPAddress(String szIPAddress) {
uint uiIP = uint.Parse(szIPAddress, System.Globalization.NumberStyles.AllowHexSpecifier);
IPAddress ip = null;
if (BitConverter.IsLittleEndian) {
uint uiIPRev = BitConverter.ToUInt32(BitConverter.GetBytes(uiIP).Reverse().ToArray(), 0);
ip = new IPAddress(uiIPRev);
} else {
ip = new IPAddress(uiIP);
}
return ip;
}
答案 1 :(得分:0)
默认情况下,数字(在您的情况下为long)以Little Endian格式存储在x86体系结构的内存中,这就是您将IP地址反转的原因。您可以在 BitConverter.IsLittleEndian 字段的帮助下查看此信息。一个简单的解决方案是反转输入字符串的字节顺序,然后将反转的字符串解析为如下所示:
string ipString = "c0a8000a";
// Reverse the HEX string byte order
int length = ipString.Length;
char[] reversedChars = new char[length];
for (int i = 0; i < length; i += 2)
{
reversedChars[i] = ipString[length - i - 2];
reversedChars[i + 1] = ipString[length - i - 1];
}
string reversedString = new string(reversedChars);
// Parse the reversed byte string
long parsedValue = long.Parse(reversedString, NumberStyles.AllowHexSpecifier);
IPAddress ip = new IPAddress(parsedValue);
答案 2 :(得分:0)
正如已经指出的那样,问题是你必须从主机字节顺序(litte endian)转换为网络字节顺序(big endian)。您可以使用IPAddress.HostToNetworkOrder
方法执行此操作:
var ip = new IPAddress(
IPAddress.HostToNetworkOrder(
int.Parse(ipString, NumberStyles.AllowHexSpecifier)
)
);
请注意,您需要使用int.Parse
而不是long.Parse
来实现此功能,因为IPv4地址是32位,而不是64位。
此方法不涉及字符串转换或使用其他类(如BitConverter
)来执行转换。