我正在寻找一个将标准IPv4地址转换为整数的函数。可用于相反功能的奖励积分。
解决方案应该在C#中。
答案 0 :(得分:135)
32位无符号整数是 IPv4地址。同时,IPAddress.Address
属性虽然已弃用,但它是一个Int64,它返回IPv4地址的无符号32位值(catch是,它是以网络字节顺序排列的,所以你需要交换它)。
例如,我的本地google.com位于64.233.187.99
。这相当于:
64*2^24 + 233*2^16 + 187*2^8 + 99
= 1089059683
事实上, http://1089059683/按预期工作(至少在Windows中,使用IE,Firefox和Chrome测试过;但在iPhone上无效)。
这是一个显示两种转换的测试程序,包括网络/主机字节交换:
using System;
using System.Net;
class App
{
static long ToInt(string addr)
{
// careful of sign extension: convert to uint first;
// unsigned NetworkToHostOrder ought to be provided.
return (long) (uint) IPAddress.NetworkToHostOrder(
(int) IPAddress.Parse(addr).Address);
}
static string ToAddr(long address)
{
return IPAddress.Parse(address.ToString()).ToString();
// This also works:
// return new IPAddress((uint) IPAddress.HostToNetworkOrder(
// (int) address)).ToString();
}
static void Main()
{
Console.WriteLine(ToInt("64.233.187.99"));
Console.WriteLine(ToAddr(1089059683));
}
}
答案 1 :(得分:38)
Int32“格式化”的IP地址可以看作以下结构
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IPv4Address
{
public Byte A;
public Byte B;
public Byte C;
public Byte D;
}
// to actually cast it from or to an int32 I think you
// need to reverse the fields due to little endian
所以要转换IP地址64.233.187.99,你可以这样做:
(64 = 0x40) << 24 == 0x40000000
(233 = 0xE9) << 16 == 0x00E90000
(187 = 0xBB) << 8 == 0x0000BB00
(99 = 0x63) == 0x00000063
---------- =|
0x40E9BB63
因此您可以使用+添加它们,或者您可以将它们组合在一起。结果是0x40E9BB63,这是1089059683.(在我看来,以十六进制查看更容易看到字节)
所以你可以把函数写成:
int ipToInt(int first, int second,
int third, int fourth)
{
return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
答案 2 :(得分:29)
要从IPv4转换为正确的整数:
IPAddress address = IPAddress.Parse("255.255.255.254");
byte[] bytes = address.GetAddressBytes();
Array.Reverse(bytes); // flip big-endian(network order) to little-endian
uint intAddress = BitConverter.ToUInt32(bytes, 0);
转回来:
byte[] bytes = BitConverter.GetBytes(4294967294);
Array.Reverse(bytes); // flip little-endian to big-endian(network order)
string ipAddress = new IPAddress(bytes).ToString();
说明:
IP地址是网络顺序(big-endian),而int
是Windows上的little-endian,因此要获得正确的值,必须在转换前反转字节。
此外,即使是IPv4
,int
也无法容纳大于127.255.255.255
的地址,例如广播地址(255.255.255.255)
,因此请使用uint
。
答案 3 :(得分:12)
试试这个:
private int IpToInt32(string ipAddress)
{
return BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(), 0);
}
private string Int32ToIp(int ipAddress)
{
return new IPAddress(BitConverter.GetBytes(ipAddress).Reverse().ToArray()).ToString();
}
答案 4 :(得分:7)
由于没有人发布使用BitConverter
的代码并实际检查字节顺序,所以这里是:
byte[] ip = address.Split('.').Select(s => Byte.Parse(s)).ToArray();
if (BitConverter.IsLittleEndian) {
Array.Reverse(ip);
}
int num = BitConverter.ToInt32(ip, 0);
并返回:
byte[] ip = BitConverter.GetBytes(num);
if (BitConverter.IsLittleEndian) {
Array.Reverse(ip);
}
string address = String.Join(".", ip.Select(n => n.ToString()));
答案 5 :(得分:6)
当面对具有非常大值的IP地址时,我遇到了所描述的解决方案的一些问题。 结果是,byte [0] * 16777216 thingy会溢出并成为负int值。 为我修好的是一种简单的铸造操作。
public static long ConvertIPToLong(string ipAddress)
{
System.Net.IPAddress ip;
if (System.Net.IPAddress.TryParse(ipAddress, out ip))
{
byte[] bytes = ip.GetAddressBytes();
return (long)
(
16777216 * (long)bytes[0] +
65536 * (long)bytes[1] +
256 * (long)bytes[2] +
(long)bytes[3]
)
;
}
else
return 0;
}
答案 6 :(得分:4)
Davy Landman功能的逆转
string IntToIp(int d)
{
int v1 = d & 0xff;
int v2 = (d >> 8) & 0xff;
int v3 = (d >> 16) & 0xff;
int v4 = (d >> 24);
return v4 + "." + v3 + "." + v2 + "." + v1;
}
答案 7 :(得分:3)
我的问题已经结束,我不知道为什么。这里接受的答案与我需要的答案不一样。
这为我提供了正确的整数值..
public double IPAddressToNumber(string IPaddress)
{
int i;
string [] arrDec;
double num = 0;
if (IPaddress == "")
{
return 0;
}
else
{
arrDec = IPaddress.Split('.');
for(i = arrDec.Length - 1; i >= 0 ; i = i -1)
{
num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
}
return num;
}
}
答案 8 :(得分:2)
将上述几个答案汇总到一个扩展方法中,该方法处理机器的Endianness并处理映射到IPv6的IPv4地址。
Traceback (most recent call last):
File "F:\web\hi.py", line 20, in <module>
writer.writerows(list_of_rows)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 0: ordinal not in range(128)
单元测试:
public static class IPAddressExtensions
{
/// <summary>
/// Converts IPv4 and IPv4 mapped to IPv6 addresses to an unsigned integer.
/// </summary>
/// <param name="address">The address to conver</param>
/// <returns>An unsigned integer that represents an IPv4 address.</returns>
public static uint ToUint(this IPAddress address)
{
if (address.AddressFamily == AddressFamily.InterNetwork || address.IsIPv4MappedToIPv6)
{
var bytes = address.GetAddressBytes();
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
return BitConverter.ToUInt32(bytes, 0);
}
throw new ArgumentOutOfRangeException("address", "Address must be IPv4 or IPv4 mapped to IPv6");
}
}
答案 9 :(得分:1)
UInt32采用适当的小端格式,这里有两个简单的转换函数:
public uint GetIpAsUInt32(string ipString)
{
IPAddress address = IPAddress.Parse(ipString);
byte[] ipBytes = address.GetAddressBytes();
Array.Reverse(ipBytes);
return BitConverter.ToUInt32(ipBytes, 0);
}
public string GetIpAsString(uint ipVal)
{
byte[] ipBytes = BitConverter.GetBytes(ipVal);
Array.Reverse(ipBytes);
return new IPAddress(ipBytes).ToString();
}
答案 10 :(得分:1)
将 IP 号码的所有部分乘以 256 的幂(256x256x256、256x256、256 和 1。例如:
IPv4 地址:127.0.0.1 32位数字: = (127x256^3) + (0x256^2) + (0x256^1) + 1 = 2130706433
答案 11 :(得分:1)
public static Int32 getLongIPAddress(string ipAddress)
{
return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0));
}
以上示例将是我的方式..您可能只需转换为UInt32用于显示目的,或字符串用途,包括将其用作字符串形式的长地址。
使用IPAddress.Parse(String)函数时需要的是什么。叹息。
答案 12 :(得分:1)
public bool TryParseIPv4Address(string value, out uint result)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(value, out ipAddress) ||
(ipAddress.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork))
{
result = 0;
return false;
}
result = BitConverter.ToUInt32(ipAddress.GetAddressBytes().Reverse().ToArray(), 0);
return true;
}
答案 13 :(得分:1)
如果您对该功能感兴趣,不仅仅是答案是如何完成的:
int ipToInt(int first, int second,
int third, int fourth)
{
return Convert.ToInt32((first * Math.Pow(256, 3))
+ (second * Math.Pow(256, 2)) + (third * 256) + fourth);
}
first
到fourth
是IPv4地址的分段。
答案 14 :(得分:0)
无论如何转换为long类型是非常困难的,因为存储64位(对于Ip不是32)并用零填充4个字节
static uint ToInt(string addr)
{
return BitConverter.ToUInt32(IPAddress.Parse(addr).GetAddressBytes(), 0);
}
static string ToAddr(uint address)
{
return new IPAddress(address).ToString();
}
享受!
的Massimo
答案 15 :(得分:0)
我认为这是错误的:“65536”==&gt; 0.0.255.255" 应该是:“65535”==&gt; 0.0.255.255“或”65536“==&gt; 0.1.0.0”
答案 16 :(得分:0)
这是我今天解决的一个解决方案(应该先用Google搜索!):
private static string IpToDecimal2(string ipAddress)
{
// need a shift counter
int shift = 3;
// loop through the octets and compute the decimal version
var octets = ipAddress.Split('.').Select(p => long.Parse(p));
return octets.Aggregate(0L, (total, octet) => (total + (octet << (shift-- * 8)))).ToString();
}
我正在使用LINQ,lambda和泛型的一些扩展,所以虽然它产生相同的结果,但它使用了一些新的语言功能,你可以用三行代码完成。
如果你有兴趣,我会在我的博客上有解释。欢呼声, -jc
答案 17 :(得分:0)
假设您有一个字符串格式的IP地址(例如,254.254.254.254)
string[] vals = inVal.Split('.');
uint output = 0;
for (byte i = 0; i < vals.Length; i++) output += (uint)(byte.Parse(vals[i]) << 8 * (vals.GetUpperBound(0) - i));
答案 18 :(得分:0)
var ipAddress = "10.101.5.56";
var longAddress = long.Parse(string.Join("", ipAddress.Split('.').Select(x => x.PadLeft(3, '0'))));
Console.WriteLine(longAddress);
输出:10101005056
答案 19 :(得分:0)
var address = IPAddress.Parse("10.0.11.174").GetAddressBytes();
long m_Address = ((address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]) & 0x0FFFFFFFF);
答案 20 :(得分:0)
我注意到System.Net.IPAddress具有Address属性(System.Int64)和构造函数,它们也接受Int64数据类型。因此,您可以使用它来将IP地址与数字格式(虽然不是Int32,而是Int64)之间进行转换。
答案 21 :(得分:-1)
看一下.Net的IPAddress.Parse中一些疯狂的解析示例: (MSDN)
“65536”==&gt; 0.0.255.255
“20.2”==&gt; 20.0.0.2
“20.65535”==&gt; 20.0.255.255
“128.1.2”==&gt; 128.1.0.2