昨天我问了一个关于将HEX字符串转换成IP的问题,并在这里得到了答案:C#将十六进制转换为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 而不是正确的那个。像Converter.aspx这样的在线工具运行得很好。它是小的还是大大小小的?我是要自己翻转绳子呢,还是有更简单的答案?
发布于 2014-11-07 12:05:02
所以一项小小的研究产生了结果,你猜对了。这和执着有关。
构造函数:IPAddress(长newAddress)期望值在网络字节顺序中,后者被定义为大端。
我假设您的系统架构很少使用endian(和大多数英特尔系统一样)。
.NET使用底层系统的特性,所以当您在这样的系统上解析long时,它就存储得很少。
这就是为什么当您通过解析整数字符串时,结果是正确的。
至于解决办法。
接下来,您将您的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;
}发布于 2014-11-07 12:05:44
默认情况下,数字(在您的例子中是长的)存储在x86体系结构内存中的小Endian格式中,这就是为什么将IP地址倒置的原因。您可以在BitConverter.IsLittleEndian字段的帮助下检查这一点。一个简单的解决方案是反转输入字符串的字节顺序,然后将反转的字符串解析为long,如下所示:
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);发布于 2014-11-07 12:14:48
正如已经指出的,问题是您必须从主机字节顺序(litte )转换为网络字节顺序(大端字节)。您可以使用IPAddress.HostToNetworkOrder方法来完成以下操作:
var ip = new IPAddress(
IPAddress.HostToNetworkOrder(
int.Parse(ipString, NumberStyles.AllowHexSpecifier)
)
);注意,您需要使用int.Parse而不是long.Parse来工作,因为在IPv4地址中是32位,而不是64位。
此方法不涉及字符串转换或使用其他类(如BitConverter )来执行转换。
https://stackoverflow.com/questions/26800243
复制相似问题