从netmask获取CIDR [英] Get CIDR from netmask

查看:108
本文介绍了从netmask获取CIDR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想出了这个来计算 CIDR ,但我很确定不是最快的方法:

I came up with this to calculate CIDR but I'm pretty sure that it isn't the most fastest way:

public int MaskToCIDR(IPAddress ip)
{
  return Convert
         .ToString(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 2)
         .ToCharArray()
         .Count(x => x == '1');
}

测试:

Console.WriteLine(MaskToCIDR(new IPAddress(new byte[]{255,255,255,255}))); // 32
Console.WriteLine(MaskToCIDR(new IPAddress(new byte[]{255,255,255,0}))); // 24
Console.WriteLine(MaskToCIDR(new IPAddress(new byte[]{255,255,0,0}))); // 16
Console.WriteLine(MaskToCIDR(new IPAddress(new byte[]{255,0,0,0}))); // 8
Console.WriteLine(MaskToCIDR(new IPAddress(new byte[]{0,0,0,0}))); // 0

是否有更快的方法以及IPv6的方式?

Is there faster way and how about IPv6?

推荐答案

根据处理无效网络掩码的方式,您可以获得10到100倍的速度提高,请参阅-有效网络掩码的c代码 https://superuser.com/questions/601252/is-225-225-225-128-a-valid-subnet-mask 。这是我的基准测试结果(花哨的是您最初的建议,出于好奇,我还尝试了恒定时间执行)。

You can get 10x-100x faster depending on how you want to handle invalid netmask see - c code for valid netmask and https://superuser.com/questions/601252/is-225-225-225-128-a-valid-subnet-mask. Here's my benchmark result (where fancy is your original proposal, I have experimented with constant time execution out of curiosity as well).

长话短说:使用二进制文件,使用常数,展开循环。 Ultra 版本可能是最好的。对于无效的网络掩码,它返回包含有效的网络掩码的最接近值。

Long story short: work in binary, use constants, unroll your loops. The Ultra version might be the best. For invalid netmask it returns the closest containing valid netmask.

现在 IPv6 怎么样?我们可能已经过早优化了……我希望没有人敢为IPv6使用老式的网络掩码表示法。

Now how about IPv6? We may have prematurely optimized... I hope nobody dares to use the old-style netmask notation for IPv6. It should be forgotten.

11111111.11111111.11111111.11111111 (255.255.255.255)
{ ns =    625,574, cidrnet = 32, method = MaskToCIDR_Fancy }
{ ns =     61,136, cidrnet = 32, method = MaskToCIDR_Fast }
{ ns =     72,039, cidrnet = 32, method = MaskToCIDR_Constant }
{ ns =      4,710, cidrnet = 32, method = MaskToCIDR_Ultra }
{ ns =     14,250, cidrnet = 32, method = MaskToCIDR_ConstantUltra }
{ ns =      8,683, cidrnet = 32, method = MaskToCIDR_Mambo }
{ ns =      7,337, cidrnet = 32, method = MaskToCIDR_PerByte }
{ ns =     37,883, cidrnet = 32, method = MaskToCIDR_BTree }
{ ns =      2,127, cidrnet = 0, method = MaskToCIDR_Empty }

11111111.11111111.11111111.00000000 (255.255.255.0)
{ ns =    486,026, cidrnet = 24, method = MaskToCIDR_Fancy }
{ ns =     47,369, cidrnet = 24, method = MaskToCIDR_Fast }
{ ns =     69,921, cidrnet = 24, method = MaskToCIDR_Constant }
{ ns =      4,835, cidrnet = 24, method = MaskToCIDR_Ultra }
{ ns =     14,079, cidrnet = 24, method = MaskToCIDR_ConstantUltra }
{ ns =      6,663, cidrnet = 24, method = MaskToCIDR_Mambo }
{ ns =      7,336, cidrnet = 24, method = MaskToCIDR_PerByte }
{ ns =     24,911, cidrnet = 24, method = MaskToCIDR_BTree }
{ ns =      2,116, cidrnet = 0, method = MaskToCIDR_Empty }

11111111.11111111.11111110.00000000 (255.255.254.0)
{ ns =    482,456, cidrnet = 23, method = MaskToCIDR_Fancy }
{ ns =     45,700, cidrnet = 23, method = MaskToCIDR_Fast }
{ ns =     68,930, cidrnet = 23, method = MaskToCIDR_Constant }
{ ns =      4,791, cidrnet = 23, method = MaskToCIDR_Ultra }
{ ns =     14,036, cidrnet = 23, method = MaskToCIDR_ConstantUltra }
{ ns =      6,951, cidrnet = 23, method = MaskToCIDR_Mambo }
{ ns =      7,377, cidrnet = 23, method = MaskToCIDR_PerByte }
{ ns =     36,027, cidrnet = 23, method = MaskToCIDR_BTree }
{ ns =      2,115, cidrnet = 0, method = MaskToCIDR_Empty }

11111111.11111111.00000000.00000000 (255.255.0.0)
{ ns =    347,425, cidrnet = 16, method = MaskToCIDR_Fancy }
{ ns =     34,460, cidrnet = 16, method = MaskToCIDR_Fast }
{ ns =     67,445, cidrnet = 16, method = MaskToCIDR_Constant }
{ ns =      4,942, cidrnet = 16, method = MaskToCIDR_Ultra }
{ ns =     15,363, cidrnet = 16, method = MaskToCIDR_ConstantUltra }
{ ns =      6,164, cidrnet = 16, method = MaskToCIDR_Mambo }
{ ns =      7,929, cidrnet = 16, method = MaskToCIDR_PerByte }
{ ns =     22,312, cidrnet = 16, method = MaskToCIDR_BTree }
{ ns =      2,116, cidrnet = 0, method = MaskToCIDR_Empty }

11111111.00000000.00000000.00000000 (255.0.0.0)
{ ns =    198,180, cidrnet = 8, method = MaskToCIDR_Fancy }
{ ns =     20,683, cidrnet = 8, method = MaskToCIDR_Fast }
{ ns =     64,785, cidrnet = 8, method = MaskToCIDR_Constant }
{ ns =      5,138, cidrnet = 8, method = MaskToCIDR_Ultra }
{ ns =     14,058, cidrnet = 8, method = MaskToCIDR_ConstantUltra }
{ ns =      6,734, cidrnet = 8, method = MaskToCIDR_Mambo }
{ ns =      8,572, cidrnet = 8, method = MaskToCIDR_PerByte }
{ ns =     37,483, cidrnet = 8, method = MaskToCIDR_BTree }
{ ns =      2,253, cidrnet = 0, method = MaskToCIDR_Empty }

10000000.00000000.00000000.00000000 (128.0.0.0)
{ ns =    198,620, cidrnet = 1, method = MaskToCIDR_Fancy }
{ ns =      7,855, cidrnet = 1, method = MaskToCIDR_Fast }
{ ns =     62,570, cidrnet = 1, method = MaskToCIDR_Constant }
{ ns =      6,317, cidrnet = 1, method = MaskToCIDR_Ultra }
{ ns =     14,145, cidrnet = 1, method = MaskToCIDR_ConstantUltra }
{ ns =      6,399, cidrnet = 1, method = MaskToCIDR_Mambo }
{ ns =      7,413, cidrnet = 1, method = MaskToCIDR_PerByte }
{ ns =     33,861, cidrnet = 1, method = MaskToCIDR_BTree }
{ ns =      2,117, cidrnet = 0, method = MaskToCIDR_Empty }

00000000.00000000.00000000.00000000 (0.0.0.0)
{ ns =     83,629, cidrnet = 0, method = MaskToCIDR_Fancy }
{ ns =      7,348, cidrnet = 0, method = MaskToCIDR_Fast }
{ ns =     63,320, cidrnet = 0, method = MaskToCIDR_Constant }
{ ns =      4,639, cidrnet = 0, method = MaskToCIDR_Ultra }
{ ns =     14,284, cidrnet = 0, method = MaskToCIDR_ConstantUltra }
{ ns =      5,438, cidrnet = 0, method = MaskToCIDR_Mambo }
{ ns =      6,767, cidrnet = 0, method = MaskToCIDR_PerByte }
{ ns =     37,961, cidrnet = 0, method = MaskToCIDR_BTree }
{ ns =      2,118, cidrnet = 0, method = MaskToCIDR_Empty }

01101111.01101111.01101111.00000000 (111.111.111.0)
{ ns =    465,689, cidrnet = 18, method = MaskToCIDR_Fancy }
{ ns =      4,242, cidrnet = -1, method = MaskToCIDR_Fast }
{ ns =     67,996, cidrnet = -1, method = MaskToCIDR_Constant }
{ ns =      5,133, cidrnet = 24, method = MaskToCIDR_Ultra }
{ ns =     14,542, cidrnet = 18, method = MaskToCIDR_ConstantUltra }
{ ns =      6,285, cidrnet = -1, method = MaskToCIDR_Mambo }
{ ns =      7,879, cidrnet = -21, method = MaskToCIDR_PerByte }
{ ns =     40,017, cidrnet = -2, method = MaskToCIDR_BTree }
{ ns =      2,115, cidrnet = 0, method = MaskToCIDR_Empty }

00000001.00000001.00000001.00000000 (1.1.1.0)
{ ns =    368,824, cidrnet = 3, method = MaskToCIDR_Fancy }
{ ns =      4,227, cidrnet = -1, method = MaskToCIDR_Fast }
{ ns =     67,043, cidrnet = -1, method = MaskToCIDR_Constant }
{ ns =      4,920, cidrnet = 24, method = MaskToCIDR_Ultra }
{ ns =     13,979, cidrnet = 3, method = MaskToCIDR_ConstantUltra }
{ ns =      6,134, cidrnet = -1, method = MaskToCIDR_Mambo }
{ ns =      7,611, cidrnet = -24, method = MaskToCIDR_PerByte }
{ ns =     39,957, cidrnet = -2, method = MaskToCIDR_BTree }
{ ns =      2,115, cidrnet = 0, method = MaskToCIDR_Empty }

和测试代码:

public class CalculateCIDRProgram
{
    private static uint[] dic = Enumerable.Range(0, 33).Select(i => i == 0 ? 0 : (uint)(~(1 << (32 - i)) + 1)).ToArray();

    private static Stopwatch __watch;

    public static void Main()
    {
        for (int i = 0; i < 33; i++)
        {
            byte[] intBytes = BitConverter.GetBytes(dic[i]);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(intBytes);
            Console.WriteLine($"{i}: {FormatBytes(intBytes)}");
        }

        __watch = Stopwatch.StartNew();
        Test(IPAddress.Parse("255.255.255.255"));
        Test(IPAddress.Parse("255.255.255.0"));
        Test(IPAddress.Parse("255.255.254.0"));
        Test(IPAddress.Parse("255.255.0.0"));
        Test(IPAddress.Parse("255.0.0.0"));
        Test(IPAddress.Parse("128.0.0.0"));
        Test(IPAddress.Parse("0.0.0.0"));
        Test(IPAddress.Parse("1.1.1.0"));
        Test(IPAddress.Parse("111.111.111.0"));
    }

    private static void Test(IPAddress ip)
    {

        WriteHeader(ip);

        var ipbytes = ip.GetAddressBytes();
        var loops = 1000000;
        //var loops = 1;
        var cidrnet = null as int?;
        var results = new List<object>();

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Fancy(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Fancy) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Fast(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Fast) });

        fakeBool = true;
        fakeInt = new Random().Next(33);
        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Constant(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Constant) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Ultra(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Ultra) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_ConstantUltra(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_ConstantUltra) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Mambo(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Mambo) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_PerByte(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_PerByte) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_BTree(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_BTree) });

        __watch.Restart();
        for (int i = 0; i < loops; i++)
            cidrnet = MaskToCIDR_Empty(ipbytes);
        results.Add(new { ns = (1000000 * __watch.Elapsed.TotalMilliseconds / loops).ToString("0.000").PadLeft(10, ' '), cidrnet, method = nameof(MaskToCIDR_Empty) });

        foreach (var result in results)
        {
            Console.WriteLine(result);
        }

        Console.WriteLine();
    }

    private static int fakeInt;
    private static bool fakeBool;

    private static int MaskToCIDR_Empty(byte[] bytes)
    {
        return 0;
    }
    private static int MaskToCIDR_BTree(byte[] bytes)
    {
        var addr = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);

        return Array.BinarySearch(dic, addr);
    }

    private static int MaskToCIDR_PerByte(byte[] bytes)
    {
        int b0 = bytes[0];
        int b1 = bytes[1];
        int b2 = bytes[2];
        int b3 = bytes[3];

        switch (b3)
        {
            case 0x00: break;
            case 0xFF: return 32;
            case 0xFE: return 31;
            case 0xFC: return 30;
            case 0xF8: return 29;
            case 0xF0: return 28;
            case 0xE0: return 27;
            case 0xC0: return 26;
            case 0x80: return 25;
            default:
                return ~(
           (b3 & 0x01) == 0 ? 32 :
           (b3 & 0x02) == 0 ? 31 :
           (b3 & 0x04) == 0 ? 30 :
           (b3 & 0x08) == 0 ? 29 :
           (b3 & 0x10) == 0 ? 28 :
           (b3 & 0x20) == 0 ? 27 :
           (b3 & 0x40) == 0 ? 26 :
                              25
           );
        }

        switch (b2)
        {
            case 0x00: break;
            case 0xFF: return 24;
            case 0xFE: return 23;
            case 0xFC: return 22;
            case 0xF8: return 21;
            case 0xF0: return 20;
            case 0xE0: return 19;
            case 0xC0: return 18;
            case 0x80: return 17;
            default:
                return ~(
           (b2 & 0x01) == 0 ? 24 :
           (b2 & 0x02) == 0 ? 23 :
           (b2 & 0x04) == 0 ? 22 :
           (b2 & 0x08) == 0 ? 21 :
           (b2 & 0x10) == 0 ? 20 :
           (b2 & 0x20) == 0 ? 19 :
           (b2 & 0x40) == 0 ? 18 :
                              17
           );
        }

        switch (b1)
        {
            case 0x00: break;
            case 0xFF: return 16;
            case 0xFE: return 15;
            case 0xFC: return 14;
            case 0xF8: return 13;
            case 0xF0: return 12;
            case 0xE0: return 11;
            case 0xC0: return 10;
            case 0x80: return 9;
            default:
                return ~(
           (b1 & 0x01) == 0 ? 16 :
           (b1 & 0x02) == 0 ? 15 :
           (b1 & 0x04) == 0 ? 14 :
           (b1 & 0x08) == 0 ? 13 :
           (b1 & 0x10) == 0 ? 12 :
           (b1 & 0x20) == 0 ? 11 :
           (b1 & 0x40) == 0 ? 10 :
                              9
           );
        }

        switch (b0)
        {
            case 0x00: break;
            case 0xFF: return 8;
            case 0xFE: return 7;
            case 0xFC: return 6;
            case 0xF8: return 5;
            case 0xF0: return 4;
            case 0xE0: return 3;
            case 0xC0: return 2;
            case 0x80: return 1;
            default:
                return ~(
           (b0 & 0x01) == 0 ? 8 :
           (b0 & 0x02) == 0 ? 7 :
           (b0 & 0x04) == 0 ? 6 :
           (b0 & 0x08) == 0 ? 5 :
           (b0 & 0x10) == 0 ? 4 :
           (b0 & 0x20) == 0 ? 3 :
           (b0 & 0x40) == 0 ? 2 :
                              1
           );
        }

        return 0;
    }

    private static int MaskToCIDR_Mambo(byte[] bytes)
    {
        var addr = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);

        switch (addr)
        {
            case 0xFFFFFFFF: return 32;
            case 0xFFFFFFFE: return 31;
            case 0xFFFFFFFC: return 30;
            case 0xFFFFFFF8: return 29;
            case 0xFFFFFFF0: return 28;
            case 0xFFFFFFE0: return 27;
            case 0xFFFFFFC0: return 26;
            case 0xFFFFFF80: return 25;
            case 0xFFFFFF00: return 24;
            case 0xFFFFFE00: return 23;
            case 0xFFFFFC00: return 22;
            case 0xFFFFF800: return 21;
            case 0xFFFFF000: return 20;
            case 0xFFFFE000: return 19;
            case 0xFFFFC000: return 18;
            case 0xFFFF8000: return 17;
            case 0xFFFF0000: return 16;
            case 0xFFFE0000: return 15;
            case 0xFFFC0000: return 14;
            case 0xFFF80000: return 13;
            case 0xFFF00000: return 12;
            case 0xFFE00000: return 11;
            case 0xFFC00000: return 10;
            case 0xFF800000: return 9;
            case 0xFF000000: return 8;
            case 0xFE000000: return 7;
            case 0xFC000000: return 6;
            case 0xF8000000: return 5;
            case 0xF0000000: return 4;
            case 0xE0000000: return 3;
            case 0xC0000000: return 2;
            case 0x80000000: return 1;
            case 0x00000000: return 0;
            default:
                return ~(
                    (addr & 0x80000000) == 0 ? 0 :
                    (addr & 0x40000000) == 0 ? 1 :
                    (addr & 0x20000000) == 0 ? 2 :
                    (addr & 0x10000000) == 0 ? 3 :
                    (addr & 0x08000000) == 0 ? 4 :
                    (addr & 0x04000000) == 0 ? 5 :
                    (addr & 0x02000000) == 0 ? 6 :
                    (addr & 0x01000000) == 0 ? 7 :
                    (addr & 0x00800000) == 0 ? 8 :
                    (addr & 0x00400000) == 0 ? 9 :
                    (addr & 0x00200000) == 0 ? 10 :
                    (addr & 0x00100000) == 0 ? 11 :
                    (addr & 0x00080000) == 0 ? 12 :
                    (addr & 0x00040000) == 0 ? 13 :
                    (addr & 0x00020000) == 0 ? 14 :
                    (addr & 0x00010000) == 0 ? 15 :
                    (addr & 0x00008000) == 0 ? 16 :
                    (addr & 0x00004000) == 0 ? 17 :
                    (addr & 0x00002000) == 0 ? 18 :
                    (addr & 0x00001000) == 0 ? 19 :
                    (addr & 0x00000800) == 0 ? 20 :
                    (addr & 0x00000400) == 0 ? 21 :
                    (addr & 0x00000200) == 0 ? 22 :
                    (addr & 0x00000100) == 0 ? 23 :
                    (addr & 0x00000080) == 0 ? 24 :
                    (addr & 0x00000040) == 0 ? 25 :
                    (addr & 0x00000020) == 0 ? 26 :
                    (addr & 0x00000010) == 0 ? 27 :
                    (addr & 0x00000008) == 0 ? 28 :
                    (addr & 0x00000004) == 0 ? 29 :
                    (addr & 0x00000002) == 0 ? 30 :
                    (addr & 0x00000001) == 0 ? 31 :
                    32);
        }
    }

    private static int MaskToCIDR_ConstantUltra(byte[] bytes)
    {
        var b0 = bytes[0];
        var b1 = bytes[1];
        var b2 = bytes[2];
        var b3 = bytes[3];

        var result =
           ((b0 & 0x80) >> 7) +
           ((b0 & 0x40) >> 6) +
           ((b0 & 0x20) >> 5) +
           ((b0 & 0x10) >> 4) +
           ((b0 & 0x08) >> 3) +
           ((b0 & 0x04) >> 2) +
           ((b0 & 0x02) >> 1) +
            (b0 & 0x01) +
           ((b1 & 0x80) >> 7) +
           ((b1 & 0x40) >> 6) +
           ((b1 & 0x20) >> 5) +
           ((b1 & 0x10) >> 4) +
           ((b1 & 0x08) >> 3) +
           ((b1 & 0x04) >> 2) +
           ((b1 & 0x02) >> 1) +
            (b1 & 0x01) +
           ((b2 & 0x80) >> 7) +
           ((b2 & 0x40) >> 6) +
           ((b2 & 0x20) >> 5) +
           ((b2 & 0x10) >> 4) +
           ((b2 & 0x08) >> 3) +
           ((b2 & 0x04) >> 2) +
           ((b2 & 0x02) >> 1) +
            (b2 & 0x01) +
           ((b3 & 0x80) >> 7) +
           ((b3 & 0x40) >> 6) +
           ((b3 & 0x20) >> 5) +
           ((b3 & 0x10) >> 4) +
           ((b3 & 0x08) >> 3) +
           ((b3 & 0x04) >> 2) +
           ((b3 & 0x02) >> 1) +
            (b3 & 0x01)
            ;

        return result;
    }


    private static int MaskToCIDR_Ultra(byte[] bytes)
    {
        var b0 = bytes[0];
        var b1 = bytes[1];
        var b2 = bytes[2];
        var b3 = bytes[3];

        return
            b3 != 0 ? (
                (b3 & 0x01) != 0 ? 32 :
                (b3 & 0x02) != 0 ? 31 :
                (b3 & 0x04) != 0 ? 30 :
                (b3 & 0x08) != 0 ? 29 :
                (b3 & 0x10) != 0 ? 28 :
                (b3 & 0x20) != 0 ? 27 :
                (b3 & 0x40) != 0 ? 26 :
                                   25) :
            b2 != 0 ? (
                (b2 & 0x01) != 0 ? 24 :
                (b2 & 0x02) != 0 ? 23 :
                (b2 & 0x04) != 0 ? 22 :
                (b2 & 0x08) != 0 ? 21 :
                (b2 & 0x10) != 0 ? 20 :
                (b2 & 0x20) != 0 ? 19 :
                (b2 & 0x40) != 0 ? 18 :
                                   17) :
            b1 != 0 ? (
                (b1 & 0x01) != 0 ? 16 :
                (b1 & 0x02) != 0 ? 15 :
                (b1 & 0x04) != 0 ? 14 :
                (b1 & 0x08) != 0 ? 13 :
                (b1 & 0x10) != 0 ? 12 :
                (b1 & 0x20) != 0 ? 11 :
                (b1 & 0x40) != 0 ? 10 :
                                   9) :
            b0 != 0 ? (
                (b0 & 0x01) != 0 ? 8 :
                (b0 & 0x02) != 0 ? 7 :
                (b0 & 0x04) != 0 ? 6 :
                (b0 & 0x08) != 0 ? 5 :
                (b0 & 0x10) != 0 ? 4 :
                (b0 & 0x20) != 0 ? 3 :
                (b0 & 0x40) != 0 ? 2 :
                                   1) :
                               0;
    }

    private static int MaskToCIDR_Constant(byte[] bytes)
    {
        int cidrnet = 0;
        var done = false;
        var invalid = false;

        for (var i = 0; i < bytes.Length; i++)
        {
            for (int v = bytes[i], j = 0; j < 8; v = v << 1, j++)
            {
                if ((v & 0x80) == 0)
                {
                    fakeBool = done;
                    done = true;
                    if (fakeBool)
                        fakeInt++;
                    else
                        fakeInt++;
                }
                else
                {
                    invalid = done;
                    fakeBool = true;
                    if (done)
                        fakeInt++;
                    else
                        cidrnet++;
                }
            }
        }

        if (invalid)
            cidrnet = ~cidrnet;
        else
            fakeInt = ~fakeInt;

        return cidrnet;
    }

    private static int MaskToCIDR_Fast(byte[] bytes)
    {
        int cidrnet = 0;
        var zeroed = false;
        for (var i = 0; i < bytes.Length; i++)
        {
            for (int v = bytes[i]; (v & 0xFF) != 0; v = v << 1)
            {
                if (zeroed)
                    // invalid netmask
                    return ~cidrnet;

                if ((v & 0x80) == 0)
                    zeroed = true;
                else
                    cidrnet++;
            }
        }
        return cidrnet;
    }

    private static int MaskToCIDR_Fancy(byte[] bytes)
    {
        return Convert
               .ToString(BitConverter.ToInt32(bytes, 0), 2)
               .ToCharArray()
               .Count(x => x == '1');
    }

    private static void WriteHeader(IPAddress ip)
    {
        var binIp = FormatBytes(ip.GetAddressBytes());
        Console.WriteLine($"{binIp} ({ip})");
    }
    private static string FormatBytes(byte[] bytes)
    {
        return string.Join(".", bytes.Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
    }
}

这篇关于从netmask获取CIDR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆