IPv6 缩写(零块压缩)逻辑。我正在使用c#

问题描述 投票:0回答:3

这是一个完整的未压缩的IP地址2001:0008:0000:CD30:0000:0000:0000:0101 我需要像这样压缩它 2001:8:0:CD30::101 但我只能像这样压缩块中的零 2001:8:0:CD30:0:0:0:101 使用此代码

 string output = "";
        string a = textBox1.Text;
        if (a.Length != 39  )
            MessageBox.Show("Invalid IP please enter the IPv6 IP in this format 6cd9:a87a:ad46:0005:ad40:0000:5698:8ab8");
        else
        {
            for (int i = 0; i < a.Length; i++)
            {
                if ((a[i] >= '1' && a[i] <= '9') || (Char.ToLower(a[i]) >= 'a' && Char.ToLower(a[i]) <= 'f') || ((i + 1) % 5 == 0 && a[i] == ':'))
                {
                    output = output + a[i];
                }
                else if ((a[i]=='0' && a[i-1]==':') || (a[i]=='0' && a[i-1]=='0' && a[i-2]==':') || (a[i]=='0' && a[i-1]=='0' && a[i-2]=='0' && a[i-3]==':')) 
                {

                }
                else if (a[i] == '0')
                {
                    output = output + a[i];
                }

                else
                {
                    MessageBox.Show("Invalid IP please enter the IPv6 IP in this format 6cd9:a87a:ad46:0005:ad40:0000:5698:8ab8");
                }
            }

            textBox2.Text = output;
        }

我使用c#,但我只需要关于如何删除整个零块的编程逻辑,问题是可能有超过1组包含ip中所有零的块,但只应该缩写一个。

c# ip logic ipv6 abbreviation
3个回答
2
投票

比我预想的要棘手得多,但在这里你可以使用正则表达式来做到这一点:

        private static string Compress(string ip)
        {
            var removedExtraZeros = ip.Replace("0000","*");

            //2001:0008:*:CD30:*:*:*:0101
            var blocks = ip.Split(':');

            var regex = new Regex(":0+");
            removedExtraZeros = regex.Replace(removedExtraZeros, ":");


            //2001:8:*:CD30:*:*:*:101

            var regex2 = new Regex(":\\*:\\*(:\\*)+:");
            removedExtraZeros = regex2.Replace(removedExtraZeros, "::");
            //2001:8:*:CD30::101

            return removedExtraZeros.Replace("*", "0");
        }

2
投票

如果您想在不使用

Regex
的情况下获得相同的结果:

public string Compress(string value)
{
    var values = value.Split(",");
    var ints = values.Select(i => int.Parse(i, System.Globalization.NumberStyles.HexNumber));
    var result = ints.Select(Conversion.Hex);
    return string.Join(":", result);
}

没有花时间进行微优化(stackalloc、span 等),但这提供了一个想法。关于优化的参考,可以看看.net core中

IPAddress.Parse
的实现。请注意
IPAddress.Parse
的结果将给出与上面示例不同的结果:

Compress        -> 2001:8:0:CD30:0:0:0:101 
IPAddress.Parse -> 2001:8:0:cd30::101

这可以通过转移到一些对象和其他想法来“清理”。

编辑:

与一位同事聊天后,我花了一些时间写了一个“优化”版本。我没有花时间清理代码,所以也许未来的编辑之一会更干净。

public string Compress(string value)
{
    Span<char> chars = stackalloc char[value.Length];
    const char zero = '0';
    const char colon = ':';
    int index = 0;
    int positionInSegment = 0;
    bool startsWithZero;

    while (index < _originalValue.Length)
    {
        startsWithZero = value[index] == zero && positionInSegment == 0;
        positionInSegment++;
        if (startsWithZero)
        {
            if (index == value.Length - 1)
            {
                chars[index] = zero;
                break;
            }
                        
            if (value[index + 1] == colon)
            {
                chars[index] = zero;
                positionInSegment = 0;
                index++;
                continue;
            }
                        
            positionInSegment = 0;
            index++;
            continue;
        }

        if (value[index] == colon)
        {
            positionInSegment = 0;
            chars[index] = colon;
            index++;
            continue;
        }
                    
        chars[index] = value[index];
        index++;
    }

    return chars.ToString();
}

我还创建了一个公共要点以供将来参考: https://gist.github.com/DeanMilojevic/7b4f1d060ce8cfa191592694b11234d7


0
投票

您可以轻松地使用 System.Net.IPAddress 类来实现此目的。

例如将字符串解析为 IPAddress 对象。

var tempIPAddress = IPAddress.Parse("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
var tempShortenedIPAddress = tempIPAddress.ToString();

// tempShortenedIPAddress  = 2001:db8:85a3::8a2e:370:7334
© www.soinside.com 2019 - 2024. All rights reserved.