I am using regular expression 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:
A subnet must start with 255.X.X.X
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:
(Optionally verify that it's even a valid IP address...)
Start at MSB, walk down bits looking for the first 0
If you find a 0 (255.255.255.255 would still be valid), check position
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;
}
Related
My assignment is to search through the binary representation of a number and replace a matched pattern of another binary representation of a number. If I get a match, I convert the matching bits from the first integer into zeroes and move on.
For example the number 469 would be 111010101 and I have to match it with 5 (101). Here's the program I've written so far. Doesn't work as expected.
using System;
namespace Conductors
{
class Program
{
static void Main(string[] args)
{
//this is the number I'm searching for a match in
int binaryTicket = 469;
//This is the pattern I'm trying to match (101)
int binaryPerforator = 5;
string binaryTicket01 = Convert.ToString(binaryTicket, 2);
bool match = true;
//in a 32 bit integer, position 29 is the last one I would
//search in, since I'm searching for the next 3
for (int pos = 0; pos < 29; pos++)
{
for (int j = 0; j <= 3; j++)
{
var posInBinaryTicket = pos + j;
var posInPerforator = j;
int bitInBinaryTicket = (binaryTicket & (1 << posInBinaryTicket)) >> posInBinaryTicket;
int bitInPerforator = (binaryPerforator & (1 << posInPerforator)) >> posInPerforator;
if (bitInBinaryTicket != bitInPerforator)
{
match = false;
break;
}
else
{
//what would be the proper bitwise operator here?
bitInBinaryTicket = 0;
}
}
Console.WriteLine(binaryTicket01);
}
}
}
}
Few things:
Use uint for this. Makes things a hell of a lot easier when dealing with binary numbers.
You aren't really setting anything - you're simply storing information, which is why you're printing out the same number so often.
You should loop the x times where x = length of the binary string (not just 29). There's no need for inner loops
static void Main(string[] args)
{
//this is the number I'm searching for a match in
uint binaryTicket = 469;
//This is the pattern I'm trying to match (101)
uint binaryPerforator = 5;
var numBinaryDigits = Math.Ceiling(Math.Log(binaryTicket, 2));
for (var i = 0; i < numBinaryDigits; i++)
{
var perforatorShifted = binaryPerforator << i;
//We need to mask off the result (otherwise we fail for checking 101 -> 111)
//The mask will put 1s in each place the perforator is checking.
var perforDigits = (int)Math.Ceiling(Math.Log(perforatorShifted, 2));
uint mask = (uint)Math.Pow(2, perforDigits) - 1;
Console.WriteLine("Ticket:\t" + GetBinary(binaryTicket));
Console.WriteLine("Perfor:\t" + GetBinary(perforatorShifted));
Console.WriteLine("Mask :\t" + GetBinary(mask));
if ((binaryTicket & mask) == perforatorShifted)
{
Console.WriteLine("Match.");
//Imagine we have the case:
//Ticket:
//111010101
//Perforator:
//000000101
//Is a match. What binary operation can we do to 0-out the final 101?
//We need to AND it with
//111111010
//To get that value, we need to invert the perforatorShifted
//000000101
//XOR
//111111111
//EQUALS
//111111010
//Which would yield:
//111010101
//AND
//111110000
//Equals
//111010000
var flipped = perforatorShifted ^ ((uint)0xFFFFFFFF);
binaryTicket = binaryTicket & flipped;
}
}
string binaryTicket01 = Convert.ToString(binaryTicket, 2);
Console.WriteLine(binaryTicket01);
}
static string GetBinary(uint v)
{
return Convert.ToString(v, 2).PadLeft(32, '0');
}
Please read over the above code - if there's anything you don't understand, leave me a comment and I can run through it with you.
In C# 4.0, whenever I compare two strings which have one or more trailing slashes, the comparison gives incorrect results:
String a = "1/2.1/";
String b = "1/2/";
if (a.CompareTo(b) > 0)
MessageBox.Show("Correct: " + a + " > " + b);
else
MessageBox.Show("Not correct: " + a + " <= " + b);
a = a.TrimEnd('/');
b = b.TrimEnd('/');
if (a.CompareTo(b) > 0)
MessageBox.Show("Trailing slash removed. Correct: " + a + " > " + b);
else
MessageBox.Show("Trailing slash removed. Not correct: " + a + " <= " + b);
Lexically speaking, "1/2.1/" comes after "1/2/", and there is not much question about that.
This behaviour also occurs in other places, such as sorting a datatable using the Select method.
Am I doing something wrong? Or is this a bug in .Net?
It should not even have anything to do with culture-specific information etc. since a slash is part of the most basic US ASCII character set.
I am running into this when comparing SQL Server hierarchyIDs. It's easy enough to solve but it is a somewhat astonishing problem.
Lexically speaking, "1/2.1/" comes after "1/2/", and there is not much question about that.
Why would it come after? On the ASCII chart, the / comes immediately after the ..
Given the following two strings, they're equal until you reach the 4th character. Then the / and . are compared, and the / is greater. So the result you're seeing (a < b) is actually correct.
1/2.1/
1/2/
After calling TrimEnd(), you end up with two different strings where and a > b.
1/2.1
1/2
If my old skill in C doesn't fail me, I think that CompareTo executes a character by character subtraction of the Integer value of the characters until the result is not zero.
After the first 3 identical characters the CompareTo looks at the fourth character, and this is a point for the first string and a slash for the second string.
The integer value of the point character is 46 while the integer value of the slash is 47, 46-47 gives back -1 so "1/2.1/" is less than "1/2/".
You can compare strings containing numbers if the numbers are right aligned:
01/02.00/
01/02.10/
01/10.00/
If this is not possible, consider creating a type for your numbers
public class ChapterNumber : IComparable<ChapterNumber>
{
private readonly decimal[] _number;
public ChapterNumber(params decimal[] number)
{
_number = number;
}
public int CompareTo(T obj)
{
var other = obj as ChapterNumber;
if (other == null) {
return +1;
}
int len = Math.Min(_number.Length, other._number.Length);
for (int i = 0; i < len; i++) {
int result = _number[i].CompareTo(other._number[i]);
if (result != 0) {
return result;
}
}
return _number.Length.CompareTo(other._number.Length);
}
public override ToString()
{
return String.Join('/', _number) + "/";
}
}
Usage:
var a = new ChapterNumber(1, 2.1m);
var b = new ChapterNumber(1, 2);
if (a.CompareTo(b) > 0) {
...
}
I have been able to achieve what I am looking for but just want to know whether there is an inbuilt method to do so?
I have a number say 2665. Now since this is a 4 digit, I need the minimum value of a 4 digit number which is 1000.
Similarly if the number is 255, the answer would be 100.
I tried this
int len = 2665.ToString().Length;
string str = string.Empty;
for (int index = 0; index < len; index++)
{
if (index == 0)
str += "1";
else
str += "0";
}
This gives correct result of 1000. But is there an inbuilt function for this?
You can use Pow and power 10 to length of string. For 1 it will give 1 for 2 it will give 10 etc.
var str = Math.Pow(10, len - 1).ToString();
You can also use constructor String(Char, Int32) of string to create the sequence of zeros you want.
string s = "1" + new string('0', str.Length-1);
I want to increase my ip address and;
Here is the code
ipAddressControl1.Text = "192.168.1.255";
byte[] ip = ipAddressControl1.GetAddressBytes();
ip[3] = (byte)(++ip[3]);
IPAddress ipAddress1 = new IPAddress(ip);
MessageBox.Show(ipAddress1.ToString());
or I also tried this
ipAddressControl3.Text = "192.168.1.255";
IPAddress ipAddress1 = new IPAddress(ıpAddressControl3.GetAddressBytes());
ipAddress1.Address += 0x1 << 24;
MessageBox.Show(ipAddress1.ToString());
but both of them gives me 192.168.1.0 but I want to get value as 192.168.2.0
Your problem is that you're not increasing ip[2] when ip[3] wraps around (and so on up the hierarchy). The following code should do the trick, finally wrapping from 255.255.255.255 to 0.0.0.0:
byte[] ip = ipAddressControl1.GetAddressBytes();
ip[3] = (byte)(ip[3] + 1);
if (ip[3] == 0) {
ip[2] = (byte)(ip[2] + 1);
if (ip[2] == 0) {
ip[1] = (byte)(ip[1] + 1);
if (ip[1] == 0) {
ip[0] = (byte)(ip[0] + 1);
}
}
}
The following may also work:
byte[] ip = ipAddressControl1.GetAddressBytes();
if (++ip[3] == 0)
if (++ip[2] == 0)
if (++ip[1] == 0)
++ip[0];
It might be worth noting that none of the existing answers handle IPv6 addresses, which the IPAddress class itself does indeed cater for. For that you'd probably want to adopt a more general strategy (and I'm not sure what the increment rules for IPv6 are like, though they could be exactly the same, just with more bytes to do it over, which I suspect is the case).
-- Edit:
On that basis, this seems to work:
public static IPAddress Increment (IPAddress address)
{
IPAddress result;
byte[] bytes = address.GetAddressBytes();
for(int k = bytes.Length - 1; k >= 0; k--){
if( bytes[k] == byte.MaxValue ){
bytes[k] = 0;
continue;
}
bytes[k]++;
result = new IPAddress(bytes);
return result;
}
// Un-incrementable, return the original address.
return address;
}
In the first example, you're only incrementing the 4th byte sequence. So it's going to go from 255 to 0 with no effect to byte[2].
In the second sequence, you're incrementing it 1, but then you're shifting it back from 2 to 1. I'm not sure why you chose to do this.
You need to check if your address is 254 - 255 and 0 are a broadcast addresses.
ipAddressControl1.Text = "192.168.1.255";
byte[] ip = ipAddressControl1.GetAddressBytes();
if (ip[3] != 255)
{
ip[3] = (byte)(++ip[3]);
}
else
{
ip[2] = (byte)(++ip[2]);
ip[3] = (byte)0;
}
IPAddress ipAddress1 = new IPAddress(ip);
MessageBox.Show(ipAddress1.ToString());
But you can only check for overflows up to ip[0] - you need to take care if you hit 255 there.
Looks like IP addresses are stored the “wrong way around” in the .Address property you tried to use:
192.168.1.255
c0 a8 01 ff is stored as 0xff01a8c0
So adding 1 << 24 is only going to increment the 0xff on the left and then truncate it, turning it into 0.
You’ll have to write your own addition function if you want this to work the way you describe.
public static IPAddress IncrementIP(IPAddress addr)
{
byte[] ip = addr.GetAddressBytes();
ip[3]++;
if (ip[3] == 0) {
ip[2]++;
if (ip[2] == 0) {
ip[1]++;
if (ip[1] == 0)
ip[0]++;
}
}
return new IPAddress(ip);
}
or something like that.
You can convert the IP into its numerical equivalent.
Check this previously answered question for details:
Best type for IP-address in Hibernate Entity?
public static string GetStandardIP(long numericIP)
{
string w = Convert.ToString(Convert.ToInt64(numericIP / 16777216) % 256);
string x = Convert.ToString(Convert.ToInt64(numericIP / 65536) % 256);
string y = Convert.ToString(Convert.ToInt64(numericIP / 256) % 256);
string z = Convert.ToString(Convert.ToInt64(numericIP) % 256);
return w + "." + x + "." + y + "." + z;
}
And this one
public static long GetNumericIP(string standardIP)
{
if (standardIP != null && standardIP != string.Empty)
{
string[] ipParts = standardIP.Split('.');
long numericIP = 16777216 * Convert.ToInt64(ipParts[0]) + 65536 * Convert.ToInt64(ipParts[1]) + 256 * Convert.ToInt32(ipParts[2]) + Convert.ToInt32(ipParts[3]);
return numericIP;
}
return 0;
}
You may want to improve them by doing checks on the parameters and use string.concat
I strongly disagree with the provided answer. It surely works, but I can see serious problems with it, starting with readability. In my opinion, readability and maintainability are paramount, and the accepted solution simply won't do. Adding to this, a more generic approach will also solve the problem for IPv6, while the accepted solution will not work.
My proposal is to use the following method:
public static IPAddress AddOne(this IPAddress ipAddress)
{
byte[] data = ipAddress.GetAddressBytes();
IncrementByOneFromRight(data, data.Length - 1);
return new IPAddress(data);
}
private static void IncrementByOneFromRight(byte[] data, int index)
{
if (index < 0)
return;
if (data[index] < byte.MaxValue)
data[index] += 1;
else
{
data[index] = 0;
IncrementByOneFromRight(data, index - 1);
}
}
Place the above in a visible static class, and the AddOne method will work as an extension method to IPAddress. This makes it easier to work with, and you will not expose the nitty-gritty implementation details of adding to the IPAddress in your class, while maintaining and readability. This will have the added benefit of not cluttering the class you are already writing with possibly unrelated methods.
Please vote up so that this is visible to people coming to this question if you agree with my answer and the reasons I disagree with the approved one.
I need an algorithm to convert an Excel Column letter to its proper number.
The language this will be written in is C#, but any would do or even pseudo code.
Please note I am going to put this in C# and I don't want to use the office dll.
For 'A' the expected result will be 1
For 'AH' = 34
For 'XFD' = 16384
public static int ExcelColumnNameToNumber(string columnName)
{
if (string.IsNullOrEmpty(columnName)) throw new ArgumentNullException("columnName");
columnName = columnName.ToUpperInvariant();
int sum = 0;
for (int i = 0; i < columnName.Length; i++)
{
sum *= 26;
sum += (columnName[i] - 'A' + 1);
}
return sum;
}
int result = colName.Select((c, i) =>
((c - 'A' + 1) * ((int)Math.Pow(26, colName.Length - i - 1)))).Sum();
int col = colName.ToCharArray().Select(c => c - 'A' + 1).
Reverse().Select((v, i) => v * (int)Math.Pow(26, i)).Sum();
Loop through the characters from last to first. Multiply the value of each letter (A=1, Z=26) times 26**N, add to a running total. My string manipulation skill in C# is nonexistent, so here is some very mixed pseudo-code:
sum=0;
len=length(letters);
for(i=0;i<len;i++)
sum += ((letters[len-i-1])-'A'+1) * pow(26,i);
Here is a solution I wrote up in JavaScript if anyone is interested.
var letters = "abc".toUpperCase();
var sum = 0;
for(var i = 0; i < letters.length;i++)
{
sum *= 26;
sum += (letters.charCodeAt(i) - ("A".charCodeAt(0)-1));
}
alert(sum);
Could you perhaps treat it like a base 26 number, and then substitute letters for a base 26 number?
So in effect, your right most digit will always be a raw number between 1 and 26, and the remainder of the "number" (the left part) is the number of 26's collected? So A would represent one lot of 26, B would be 2, etc.
As an example:
B = 2 = Column 2
AB = 26 * 1(A) + 2 = Column 28
BB = 26 * 2(B) + 2 = Column 54
DA = 26 * 4(D) + 1 = Column 105
etc
Shorter version:
int col = "Ab".Aggregate(0, (a, c) => a * 26 + c & 31); // 28
To ignore non A-Za-z characters:
int col = " !$Af$3 ".Aggregate(0, (a, c) => (uint)((c | 32) - 'a') > 25 ? a : a * 26 + (c & 31)); // 32
Here is a basic c++ answer for those who are intrested in c++ implemention.
int titleToNumber(string given) {
int power=0;
int res=0;
for(int i=given.length()-1;i>=0;i--)
{
char c=given[i];
res+=pow(26,power)*(c-'A'+1);
power++;
}
return res;
}
in Excel VBA you could use the .Range Method to get the number, like so:
Dim rng as Range
Dim vSearchCol as variant 'your input column
Set rng.Thisworkbook.worksheets("mySheet").Range(vSearchCol & "1:" & vSearchCol & "1")
Then use .column property:
debug.print rng.column
if you need full code see below:
Function ColumnbyName(vInput As Variant, Optional bByName As Boolean = True) As Variant
Dim Rng As Range
If bByName Then
If Not VBA.IsNumeric(vInput) Then
Set Rng = ThisWorkbook.Worksheets("mytab").Range(vInput & "1:" & vInput & "1")
ColumnbyName = Rng.Column
Else
MsgBox "Please enter valid non Numeric column or change paramter bByName to False!"
End If
Else
If VBA.IsNumeric(vInput) Then
ColumnbyName = VBA.Chr(64 + CInt(vInput))
Else
MsgBox "Please enter valid Numeric column or change paramter bByName to True!"
End If
End If
End Function
I guess this essentially works out pretty much the same as some of the other answers, but it may make a little more clear what's going on with the alpha equivalent of a numeric digit. It's not quite a base 26 system because there is no 0 placeholder. That is, the 26th column would be 'A0' or something instead of Z in base 26. And it's not base 27 because the 'alpha-gits' don't represent powers of 27. Man, it really makes you appreciate what a mess arithmetic must have been before the Babylonians invented the zero!
UInt32 sum = 0, gitVal = 1;
foreach (char alphagit in ColumnName.ToUpperInvariant().ToCharArray().Reverse())
{
sum += gitVal * (UInt32)(alphagit - 'A' + 1)
gitVal *= 26;
}
Like some others, I reversed the character array so I don't need to know anything about exponents.
For this purpose I use only one line:
int ColumnNumber = Application.Range[MyColumnName + "1"].Column;