开发者

Regular expression for subnet masking?

I am using regular expressio开发者_StackOverflow中文版n for checking the subnet masking. I use ajax txtbox with masking value but that is not working, then I switched to a textbox and applying a regular expression for that. unfortunatly that one is also not working.

Can you help me out to give a RE for subnet masking 255.255.255.255

Or any best way to do that?

Solution:

I was using masked text box and don't know how to put validation expression.

Finally I found a property of masked text box as validation expression, and there I put the RE and change the property validate to true.

No need to use validator expression explicitly.

Thanks


To do this with a regular expression, you have to ensure that the entire IPv4 dotted quad represents a 32 bit number with leading ones only. It is not enough to ensure that each number in the quad has only leading ones. For example, 255.192.255.0 is not a valid submask, even though each number in the quad has only leading ones. Building on the solution offered by @xanatos,

var leadingOnes = new Regex("255|254|252|248|240|224|192|128|0+");

defines a regular expression that will match any 8-bit (decimal) number with leading ones only. I have used "0+" to allow for .000, which is sometimes used in quads. Obviously, if you want to force a singe zero, use "0" instead.

You then have to build up a regular expression that matches any one of the four following patterns, which I represent as pseudo regular expressions to make it easer to understand:

  • 255.255.255.leadingOnes
  • 255.255.leadingOnes*.0
  • 255.leadingOnes.0.0
  • leadingOnes.0.0.0

You can either write this out as a single string, or build it up through concatenation. Here's building it up:

var leadingOnes = "(255|254|252|248|240|224|192|128|0+);"
var allOnes = @"(255\.)"; 
var re = new Regex("^((" + allOnes + "{3}" + leadingOnes + ")|" +
                     "(" + allOnes + "{2}" + leadingOnes + @"\.0+)|" +
                     "(" + allOnes +         leadingOnes + @"(\.0+){2})|" +
                     "(" +                   leadingOnes + @"(\.0+){3}))$");

And here's the entire string, if we ignore line breaks.

var re = new Regex(@"^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$");

Following @Keith's suggestion, you could start with a simple regular expression such as

Regex("([0-9]{1,3}\.){3}[0-9]{1,3}" to get four 3-digit numbers separated by dots, and then write a function that extracts and evaluates the four pieces into a 32-bit integer that you then check to ensure that it has only leading ones. There are several ways to do that, but all of them require up to 31 compare operations to complete the validation.


If you want to accept any IP address as a subnet mask:

var num = @"(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})";
var rx = new Regex("^" + num + @"\." + num + @"\." + num + @"\." + num + "$");

I considered easier to split the "repeating" match for a single group of numbers in a separate variable.

As an exercise for the reader, I'll give another variant of the expression. This one will capture all the numbers in the same group but different captures:

var rx = new Regex("^(?:" + num + @"(?:\.(?!$)|$)){4}$");

BUT it's wrong, you should use this

var num = @"(255|254|252|248|240|224|192|128|0+)";
var rx = new Regex("^" + num + @"\." + num + @"\." +num + @"\." +num + "$");

or

var rx = new Regex("^(?:" + num + @"(?:\.(?!$)|$)){4}$");

http://www.freesoft.org/CIE/Course/Subnet/6.htm


I know the question asked about a Regex expression, but for anyone else who's interested, here are two iterative solutions to the problem. The second function is a bit faster than the first.

private bool IsValidSubnet(IPAddress ip) {
    byte[] validOctets = new byte[] { 255, 254, 252, 248, 240, 224, 192, 128, 0 };
    byte[] ipOctets = ip.GetAddressBytes();
    bool restAreZeros = false;
    for (int i = 0; i < 4; i++) {
        if (!validOctets.Contains(ipOctets[i]))
            return false;
        if (restAreZeros && ipOctets[i] != 0)
            return false;
        if (ipOctets[i] < 255)
            restAreZeros = true;
    }
    return true;
}

// checks if the address is all leading ones followed by only zeroes
private bool IsValidSubnet2(IPAddress ip) {
    byte[] ipOctets = ip.GetAddressBytes();
    bool restAreOnes = false;
    for (int i = 3; i >= 0; i--) {
        for (int j = 0; j < 8; j++) {
            bool bitValue = (ipOctets[i] >> j & 1) == 1;
            if (restAreOnes && !bitValue)
                return false;
            restAreOnes = bitValue;
        }
    }
    return true;
}


From http://pastebin.com/wTEKjKpP

var subnetRegex = /^((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0\.0)|(255\.(((0|128|192|224|240|248|252|254)\.0)|255\.(0|128|192|224|240|248|252|254)))))$/

Of course that's for javascript, but that should help.


you can use this regex to validate subnet

^(((255\.){3}(255|254|252|248|240|224|192|128+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$ 


Explanation

A little late to the party, but we can't do just a regex check on valid octets because:

  1. A subnet must start with 255.X.X.X
  2. A subnet cannot look like this: 255.254.128.X - once there is 0 bit, everything else must be 0 afterwards

The correct way to do this is to walk the bits from the MSB, checking for the first 0 bit. Once you discover the first 0 bit, check what position it's in. The largest legal subnet is a /8, or 255.0.0.0, meaning there needs to be 8 1 bits before the first zero. Then, make sure every bit after the first 0 is a zero. So in summary:

  1. (Optionally verify that it's even a valid IP address...)

  2. Start at MSB, walk down bits looking for the first 0

  3. If you find a 0 (255.255.255.255 would still be valid), check position
  4. Check that all remaining bits are zero

Code

    private bool IsValidSubnet(string subnet)
    {
        //A subnet is a valid ipv4 address, so start checking there
        if (!IsIPv4(subnet)) return false;

        // Get the 4 bytes
        byte[] subnetMaskBytes =
                    System.Net.IPAddress.Parse(subnet).GetAddressBytes();

        //Shift to get uint representation of the bits
        var UintSubnet = (uint)subnetMaskBytes[0] << 24;
        UintSubnet += (uint)subnetMaskBytes[1] << 16;
        UintSubnet += (uint)subnetMaskBytes[2] << 8;
        UintSubnet += (uint)subnetMaskBytes[3];

        int i = 31;
        while (i >= 0)
        {
            UInt32 mask = (UInt32)(1 << i);
            if ((UintSubnet & mask) == 0) break;
            i--;
        }

        // It is not legal to have fewer than 8 bits of addressing
        if (i >= 24) return false;

        // Make sure that all remaining bits are 0
        while (i >= 0)
        {
            UInt32 mask = (UInt32)(1 << i);
            if ((UintSubnet & mask) != 0) return false;
            i--;
        }
        return true;
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜