Конвертировать.NET System.Int64 в IP-адрес
У меня есть следующий объект System.Net.IPAddress в Windbg, и я хотел бы преобразовать поле m_address (4294967295 m_Address) в соответствующую нотацию с точечными квадратами. Как я могу сделать это? Я вижу, что m_ToString имеет значение 00000000. Как получается эта строка?
Name: System.Net.IPAddress
MethodTable: 71c3d860
EEClass: 71a299f0
Size: 40(0x28) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
Fields:
MT Field Offset Type VT Attr Value Name
727e821c 40018b1 4 System.Int64 1 instance 4294967295 m_Address
727f2248 40018b2 14 System.String 0 instance 00000000 m_ToString
71c42030 40018b6 1c System.Int32 1 instance 2 m_Family
727e1994 40018b7 18 System.UInt16[] 0 instance 022c20a8 m_Numbers
727e821c 40018b8 c System.Int64 1 instance 0 m_ScopeId
727f3aa4 40018b9 20 System.Int32 1 instance 0 m_HashCode
71c3d860 40018ad 7ec System.Net.IPAddress 0 static 022c1ff8 Any
71c3d860 40018ae 7f0 System.Net.IPAddress 0 static 022c203c Loopback
71c3d860 40018af 7f4 System.Net.IPAddress 0 static 022c2080 Broadcast
71c3d860 40018b0 7f8 System.Net.IPAddress 0 static 022c2080 None
71c3d860 40018b3 7fc System.Net.IPAddress 0 static 022c20c4 IPv6Any
71c3d860 40018b4 800 System.Net.IPAddress 0 static 022c2108 IPv6Loopback
71c3d860 40018b5 804 System.Net.IPAddress 0 static 022c214c IPv6None
Таким образом, кажется, что в точке останова поле m_Address не имело адреса. После выполнения метода UdpClient.Receive. Я получаю следующее.
0:000> !DumpObj /d 024a20f8
Name: System.Net.IPAddress
MethodTable: 71c3d860
EEClass: 71a299f0
Size: 40(0x28) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll
Fields:
MT Field Offset Type VT Attr Value Name
727e821c 40018b1 4 System.Int64 1 instance 100731402 m_Address
727f2248 40018b2 14 System.String 0 instance 024a2198 m_ToString
71c42030 40018b6 1c System.Int32 1 instance 2 m_Family
727e1994 40018b7 18 System.UInt16[] 0 instance 024a2120 m_Numbers
727e821c 40018b8 c System.Int64 1 instance 0 m_ScopeId
727f3aa4 40018b9 20 System.Int32 1 instance 0 m_HashCode
71c3d860 40018ad 7ec System.Net.IPAddress 0 static 022c1ff8 Any
71c3d860 40018ae 7f0 System.Net.IPAddress 0 static 022c203c Loopback
71c3d860 40018af 7f4 System.Net.IPAddress 0 static 022c2080 Broadcast
71c3d860 40018b0 7f8 System.Net.IPAddress 0 static 022c2080 None
71c3d860 40018b3 7fc System.Net.IPAddress 0 static 022c20c4 IPv6Any
71c3d860 40018b4 800 System.Net.IPAddress 0 static 022c2108 IPv6Loopback
71c3d860 40018b5 804 System.Net.IPAddress 0 static 022c214c IPv6None
0:000> !DumpObj /d 024a2198
Name: System.String
MethodTable: 727f2248
EEClass: 72423444
Size: 32(0x20) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: 10.10.1.6
Fields:
MT Field Offset Type VT Attr Value Name
727f3aa4 40000aa 4 System.Int32 1 instance 9 m_stringLength
727f2c40 40000ab 8 System.Char 1 instance 31 m_firstChar
727f2248 40000ac c System.String 0 shared static Empty
Но остается вопрос, какова математическая формула для преобразования Int64 в IP-адрес?
2 ответа
IP-адрес составляет 4 8 битных октетов.
Например, значение 0x2414188f в формате с прямым порядком байтов будет IP-адресом "143.24.20.36".
605296783 == 0x2414188f
0x2414188f == 100100000101000001100010001111
00100100. 00010100. 00011000. 10001111
Поскольку это Big Endian, вам нужно изменить порядок байтов так
00100100 == 36
00010100 == 20
00011000 == 24
10001111 == 143
Другими словами, возьмите значение Int64 (также называемое long). Преобразуйте его в двоичное представление (byte[]). Прочитайте первый байт и преобразуйте его в int. Это будет 4-й (последний) октет IP-адреса. Прочитайте второй байт, преобразованный в int, это третий октет ip. Прочитайте третий байт, это второй октет. Прочитайте последний байт, это 1-й октет.
У меня нет моей IDE прямо сейчас, но это должно сработать
var bytes = BitConverter.GetBytes(value);
var fourthOctet = BitConverter.ToInt32(bytes,0);
var thirdOctet = BitConverter.ToInt32(bytes,1);
var secondOctet = BitConverter.ToInt32(bytes,2);
var firstOctet = BitConverter.ToInt32(bytes,3);
using System;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
namespace SOFAcrobatics
{
public static class Launcher
{
public static void Main ()
{
Console.WriteLine(Launcher.IPv4ToQuadNotation(new IPAddress(4294967295)));
// outputs 255.255.255.255
Console.ReadKey(true);
}
public static String IPv4ToQuadNotation (IPAddress ip)
{
String output = String.Empty;
foreach (Match m in Regex.Matches(ip.Address.ToString("X8"), @"[A-F0-9]{2}"))
{
output += (Int32.Parse(m.Value, NumberStyles.HexNumber) + ".");
}
return output.Substring(0, (output.Length - 1));
}
}
}