137 lines
4 KiB
C#
137 lines
4 KiB
C#
using System;
|
|
using System.Text.RegularExpressions;
|
|
using System.Text;
|
|
|
|
class ParseIPAddress
|
|
{
|
|
private static readonly Regex IPV4_PAT = new Regex(@"^(\d+)\.(\d+)\.(\d+)\.(\d+)(?::(\d+)){0,1}$");
|
|
private static readonly Regex IPV6_DOUBL_COL_PAT = new Regex(@"^\[{0,1}([0-9a-f:]*)::([0-9a-f:]*)(?:\]:(\d+)){0,1}$");
|
|
private static readonly Regex IPV6_PAT;
|
|
|
|
static ParseIPAddress()
|
|
{
|
|
string ipv6Pattern = @"^\[{0,1}";
|
|
for (int i = 1; i <= 7; i++)
|
|
{
|
|
ipv6Pattern += @"([0-9a-f]+):";
|
|
}
|
|
ipv6Pattern += @"([0-9a-f]+)(?:\]:(\d+)){0,1}$";
|
|
IPV6_PAT = new Regex(ipv6Pattern);
|
|
}
|
|
|
|
static void Main(string[] args)
|
|
{
|
|
string[] tests = new string[] { "192.168.0.1", "127.0.0.1", "256.0.0.1", "127.0.0.1:80", "::1", "[::1]:80", "[32e::12f]:80", "2605:2700:0:3::4713:93e3", "[2605:2700:0:3::4713:93e3]:80", "2001:db8:85a3:0:0:8a2e:370:7334" };
|
|
Console.WriteLine(String.Format("{0,-40} {1,-32} {2}", "Test Case", "Hex Address", "Port"));
|
|
foreach (var ip in tests)
|
|
{
|
|
try
|
|
{
|
|
string[] parsed = ParseIP(ip);
|
|
Console.WriteLine(String.Format("{0,-40} {1,-32} {2}", ip, parsed[0], parsed[1]));
|
|
}
|
|
catch (ArgumentException e)
|
|
{
|
|
Console.WriteLine(String.Format("{0,-40} Invalid address: {1}", ip, e.Message));
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static string[] ParseIP(string ip)
|
|
{
|
|
string hex = "";
|
|
string port = "";
|
|
|
|
// IPV4
|
|
Match ipv4Matcher = IPV4_PAT.Match(ip);
|
|
if (ipv4Matcher.Success)
|
|
{
|
|
for (int i = 1; i <= 4; i++)
|
|
{
|
|
hex += ToHex4(ipv4Matcher.Groups[i].Value);
|
|
}
|
|
if (ipv4Matcher.Groups[5].Success)
|
|
{
|
|
port = ipv4Matcher.Groups[5].Value;
|
|
}
|
|
return new string[] { hex, port };
|
|
}
|
|
|
|
// IPV6, double colon
|
|
Match ipv6DoubleColonMatcher = IPV6_DOUBL_COL_PAT.Match(ip);
|
|
if (ipv6DoubleColonMatcher.Success)
|
|
{
|
|
string p1 = ipv6DoubleColonMatcher.Groups[1].Value;
|
|
if (p1 == "")
|
|
{
|
|
p1 = "0";
|
|
}
|
|
string p2 = ipv6DoubleColonMatcher.Groups[2].Value;
|
|
if (p2 == "")
|
|
{
|
|
p2 = "0";
|
|
}
|
|
ip = p1 + GetZero(8 - NumCount(p1) - NumCount(p2)) + p2;
|
|
if (ipv6DoubleColonMatcher.Groups[3].Success)
|
|
{
|
|
ip = "[" + ip + "]:" + ipv6DoubleColonMatcher.Groups[3].Value;
|
|
}
|
|
}
|
|
|
|
// IPV6
|
|
Match ipv6Matcher = IPV6_PAT.Match(ip);
|
|
if (ipv6Matcher.Success)
|
|
{
|
|
for (int i = 1; i <= 8; i++)
|
|
{
|
|
hex += String.Format("{0,4}", ToHex6(ipv6Matcher.Groups[i].Value)).Replace(" ", "0");
|
|
}
|
|
if (ipv6Matcher.Groups[9].Success)
|
|
{
|
|
port = ipv6Matcher.Groups[9].Value;
|
|
}
|
|
return new string[] { hex, port };
|
|
}
|
|
|
|
throw new ArgumentException("ERROR 103: Unknown address: " + ip);
|
|
}
|
|
|
|
private static int NumCount(string s)
|
|
{
|
|
return s.Split(':').Length;
|
|
}
|
|
|
|
private static string GetZero(int count)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(":");
|
|
while (count > 0)
|
|
{
|
|
sb.Append("0:");
|
|
count--;
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
private static string ToHex4(string s)
|
|
{
|
|
int val = int.Parse(s);
|
|
if (val < 0 || val > 255)
|
|
{
|
|
throw new ArgumentException("ERROR 101: Invalid value : " + s);
|
|
}
|
|
return val.ToString("X2");
|
|
}
|
|
|
|
private static string ToHex6(string s)
|
|
{
|
|
int val = int.Parse(s, System.Globalization.NumberStyles.HexNumber);
|
|
if (val < 0 || val > 65536)
|
|
{
|
|
throw new ArgumentException("ERROR 102: Invalid hex value : " + s);
|
|
}
|
|
return s;
|
|
}
|
|
}
|