Is there a method in c# that would talk the ip address 10.13.216.41
and display it as 00001010.00001101.11011000.00101001. If not, how can it be done?
While I won't rewrite the format-as-binary code (Larsenal's answer was fine), I'll point out that splitting on "." won't work for IPv6 addresses. If you use IPAddress.Parse, though, it will work for any address format. You can then use IPAddress.GetAddressBytes to get each part of the address.
So instead of:
input.Split('.').Select( ... )
do:
IPAddress.Parse(input).GetAddressBytes().Select( ... )
static string IPAddrToBinary( string input) {
// assumes a valid IP Address format
return String.Join(".", (input.Split('.').Select(x => Convert.ToString(Int32.Parse(x), 2).PadLeft(8, '0'))).ToArray());
}
Here's a version with comments, which may be a little easier to understand:
static string IPAddrToBinary(string input)
{
return String.Join(".", ( // join segments
input.Split('.').Select( // split segments into a string[]
// take each element of array, name it "x",
// and return binary format string
x => Convert.ToString(Int32.Parse(x), 2).PadLeft(8, '0')
// convert the IEnumerable<string> to string[],
// which is 2nd parameter of String.Join
)).ToArray());
}
First, you would need to get the number you want to convert to binary (using String.Split, for example). Then, you can use an overload of the Convert.ToString method to return a string of the specified number in the specified base. For example:
Convert.ToString (128, 2);
returns
10000000
Funny, I wrote a javascript version of this today for another question.
Here's the c# translation of that code:
int dottedQuadToInt(string ip)
{
var parts = ip.Split(new char[] {'.'}, 4);
if (parts.Length != 4) return -1;
var result = 0;
var bitPos = 1;
foreach(var part in parts)
{
//validation
if (part.Length == 0 || part.Length > 3) return -1;
int segment;
if (!int.TryParse(part, out segment) || segment<0 || segment > 255) return -1;
//compute next segment
result += bitPos * segment;
bitPos = bitPos << 8;
}
return result;
}
Now, this isn't exactly what you asked for, but it's arguably more useful and it shoudl point you in the right direction.
You could do:
var parts = (from p in ("10.13.216.41").Split('.')
select int.Parse(p)).ToArray();
string result = string.Format("{0}.{1}.{2}.{3}",
Convert.ToString(part[0], 2).PadLeft(8,'0'),
Convert.ToString(part[1], 2).PadLeft(8,'0'),
Convert.ToString(part[2], 2).PadLeft(8,'0'),
Convert.ToString(part[3], 2).PadLeft(8,'0'));
This method can help you:
static string IPDecToBinary(string IPAdresa)
{
string IPverBinare = null;
IPAddress IPDec = IPAddress.Parse(IPAdresa);
byte[] IPByte = IPDec.GetAddressBytes();
IPverBinare = string.Format("{0}.{1}.{2}.{3}",
Convert.ToString(IPByte[0], 2).PadLeft(8, '0'),
Convert.ToString(IPByte[1], 2).PadLeft(8, '0'),
Convert.ToString(IPByte[2], 2).PadLeft(8, '0'),
Convert.ToString(IPByte[3], 2).PadLeft(8, '0')
);
return IPverBinare;
}
Related
I have a method which gets two string. These strings can contain numbers, ASCII chars or both at the same time.
The algorithm works like this:
Split both strings into char Arrays A and B.
Try to parse element Ai and Bi to an int
Compare element Ai with element Bi, in case of integers use direct comparison, in case of chars use ordinal string comparison.
Do work based on the result
Now, I'm wondering: Do I really need to parse the elements to int? I simply could compare each element in an ordinal string comparison and would get the same result, right?
What are the performance implications here? Is parsing and normal comparison faster than ordinal string comparison? Is it slower?
Is my assumption (using ordinal string comparison instead of parsing and comparing) correct?
Here is the method in question:
internal static int CompareComponentString(this string componentString, string other)
{
bool componentEmpty = string.IsNullOrWhiteSpace(componentString);
bool otherEmtpy = string.IsNullOrWhiteSpace(other);
if (componentEmpty && otherEmtpy)
{
return 0;
}
if (componentEmpty)
{
return -1;
}
if (otherEmtpy)
{
return 1;
}
string[] componentParts = componentString.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
string[] otherParts = other.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < Math.Min(componentParts.Length, otherParts.Length); i++)
{
string componentChar = componentParts[i];
string otherChar = otherParts[i];
int componentNumVal, otherNumVal;
bool componentIsNum = int.TryParse(componentChar, out componentNumVal);
bool otherIsNum = int.TryParse(otherChar, out otherNumVal);
if (componentIsNum && otherIsNum)
{
if (componentNumVal.CompareTo(otherNumVal) == 0)
{
continue;
}
return componentNumVal.CompareTo(otherNumVal);
}
else
{
if (componentIsNum)
{
return -1;
}
if (otherIsNum)
{
return 1;
}
int comp = string.Compare(componentChar, otherChar, StringComparison.OrdinalIgnoreCase);
if (comp != 0)
{
return comp;
}
}
}
return componentParts.Length.CompareTo(otherParts.Length);
}
This are strings that might be used. I might add only the part after the minus sign is used.
1.0.0-alpha
1.0.0-alpha.1
1.0.0-alpha.beta
1.0.0-beta.2
With this method you can create a compare string for each of your string. These strings are comparable by simple alphanumeric comparison.
Assumptions:
There is a minus in the string separating the common part and the indiv part
before the minus is always a substring of three integer values divided by a dot
These integer values are not higher than 999 (look at variable "MaxWidth1")
behind the minus is another substring consisting of several parts, also divided by a dot
The second substring's parts may be numeric or alphanumeric with a max. width of 7 (look at "MaxWidth2")
The second substring consists of max. 5 parts (MaxIndivParts)
Put this method wherever you want:
public string VersionNumberCompareString(string versionNumber, int MaxWidth1=3, int MaxWidth2=7,int MaxIndivParts=5){
string result = null;
int posMinus = versionNumber.IndexOf('-');
string part1 = versionNumber.Substring(0, posMinus);
string part2 = versionNumber.Substring(posMinus+1);
var integerValues=part1.Split('.');
result = integerValues[0].PadLeft(MaxWidth1, '0');
result += integerValues[1].PadLeft(MaxWidth1, '0');
result += integerValues[2].PadLeft(MaxWidth1, '0');
var alphaValues = part2.Split('.');
for (int i = 0; i < MaxIndivParts;i++ ) {
if (i <= alphaValues.GetUpperBound(0)) {
var s = alphaValues[i];
int casted;
if (int.TryParse(s, out casted)) //if int: treat as number
result += casted.ToString().PadLeft(MaxWidth2, '0');
else //treat as string
result += s.PadRight(MaxWidth2, ' ');
}
else
result += new string(' ', MaxWidth2);
}
return result; }
You call it like this:
var s1 = VersionNumberCompareString("1.3.0-alpha.1.12");
//"001003000alpha 00000010000012 "
var s2 = VersionNumberCompareString("0.11.4-beta");
//"000011004beta "
var s3 = VersionNumberCompareString("2.10.11-beta.2");
//"002010011beta 0000002 "
Be aware of the final " sign. All strings are of the same length!
Hope this helps...
that's .net comparison logic for ascii strings -
private unsafe static int CompareOrdinalIgnoreCaseHelper(String strA, String strB)
{
Contract.Requires(strA != null);
Contract.Requires(strB != null);
Contract.EndContractBlock();
int length = Math.Min(strA.Length, strB.Length);
fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
{
char* a = ap;
char* b = bp;
while (length != 0)
{
int charA = *a;
int charB = *b;
Contract.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
// uppercase both chars - notice that we need just one compare per char
if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
//Return the (case-insensitive) difference between them.
if (charA != charB)
return charA - charB;
// Next char
a++; b++;
length--;
}
return strA.Length - strB.Length;
}
}
having said that, Unless you have a strict performance constaint, i would say if you get the same result from an already implemented & tested function, its better to reuse it and not to reinvent the wheel.
It saves so much time in implementation, unit testing, debugging & bug fixing time. & helps keep the software simple.
I need to format an integer as a MAC-Address (01-1A-1B-2B-30 and so on). Is there a way to to this directly with string.format()?
All my attepts so far have failed:
string.Format("{0:X}", 1234567); //Output: 12D687 It is hex, but not formatted
string.Format("{0:00-00-00-00}", 1234567); //Output: 01-23-45-67 Formatted, but not hex
string.Format("{0:00-00-00-00}", string.Format("{0:X}", 1234567)); //Output: 01-23-45-67 Also dosn't work and is ugly.
string.Format("{0:X00-00-00-00}", 1234567); //Output: X01-23-45-67 Well. Still no success here.
This will include a - delimiter;
BitConverter.ToString(BitConverter.GetBytes(1234567))
Use
BitConverter.ToString(BitConverter.GetBytes(1234567))
You need to have a placeholder for each byte, and pass the integer in as an array:
// We have a format string that spits out hex for each byte seperated by a dash.
// ToString expects either a params or an object array, so let's get the bytes
// as a byte array, and convert it to an array of object
String.Format("{0:X}-{1:X}-{2:X}-{3:X}", BitConverter.GetBytes(1234567).Cast<Object>().ToArray())
Once you turn it into a hex string, you could use this method to split it up into chunkSize 2, then rejoin it with hyphens
void Main()
{
var str = string.Format("{0:X}", 12345678);
var splits = Split(str, 2);
var rejoinedSplits = string.Join("-",splits);
Console.WriteLine (rejoinedSplits); //tested in linqpad, gave me BC-61-4E
}
static IEnumerable<string> Split(string str, int chunkSize)
{
return Enumerable.Range(0, str.Length / chunkSize).Select(i => str.Substring(i * chunkSize, chunkSize));
}
Use the following function to separate every 4 digits:
public static string NumberToHexStr<T>(T obj) where T : IComparable, IFormattable, IConvertible // Any Number Type
{
string strHex = string.Format("0x{0:X2}", obj);
if (strHex.Length > 6)
{
while (((strHex.Length - 2) % 4) != 0)
strHex = strHex.Insert(2, "0");
int nIndex = strHex.Length - 4;
while (nIndex > 2)
{
strHex = strHex.Insert(nIndex, " ");
nIndex -= 4;
}
}
return strHex;
}
Example: 1,407,392,063,619,074 will be displayed as 0x0005 0004 0003 0002.
string word = "hello";
So what I want to do is slice the string so that I can print, for example, elloh to the console window. In python it's so simple but I'm not sure if there's a specific method for slicing in c#.
A string can be indexed to get characters:
string word = "hello";
char h = word[0];
or strings have methods for "slicing":
int start = 0;
int length = 1;
string h = word.Substring(start, length);
Why not read the docs and find out for yourself?
There's no exact translation from the concept of a slicing, but a Substring is generally what you want.
It is unclear to me what your exact criteria is to slice it up, but this would do what you want:
void Main()
{
var input = "hello";
var output = input.Substring(1, input.Length - 1) + input.Substring(0, 1);
Console.WriteLine (output);
}
To "slice" a string, you use the Substring method:
string word = "hello";
string ordw = word.Substring(1) + word.Substring(0, 1);
However, a different answer would be to check out NSlice, a library built to handle python-like slicing of arrays.
Will it make it easier to do what you asked? No. Will it make it easier to "slice" different kinds of collections? Possibly.
you should use the substring function of string:
word.Substring(1);
http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
Maybe you want an extension method like this:
public static string Rotate(this string s, int numberOfChars)
{
if (string.IsNullOrEmpty(s))
return s;
numberOfChars %= s.Length;
if (numberOfChars == 0)
return s;
if (numberOfChars < 0)
numberOfChars += s.Length;
return s.Substring(numberOfChars) + s.Remove(numberOfChars);
}
How to remove leading zeros in strings using C#?
For example in the following numbers, I would like to remove all the leading zeros.
0001234
0000001234
00001234
This is the code you need:
string strInput = "0001234";
strInput = strInput.TrimStart('0');
It really depends on how long the NVARCHAR is, as a few of the above (especially the ones that convert through IntXX) methods will not work for:
String s = "005780327584329067506780657065786378061754654532164953264952469215462934562914562194562149516249516294563219437859043758430587066748932647329814687194673219673294677438907385032758065763278963247982360675680570678407806473296472036454612945621946";
Something like this would
String s ="0000058757843950000120465875468465874567456745674000004000".TrimStart(new Char[] { '0' } );
// s = "58757843950000120465875468465874567456745674000004000"
Code to avoid returning an empty string ( when input is like "00000").
string myStr = "00012345";
myStr = myStr.TrimStart('0');
myStr = myStr.Length > 0 ? myStr : "0";
return numberString.TrimStart('0');
Using the following will return a single 0 when input is all 0.
string s = "0000000"
s = int.Parse(s).ToString();
TryParse works if your number is less than Int32.MaxValue. This also gives you the opportunity to handle badly formatted strings. Works the same for Int64.MaxValue and Int64.TryParse.
int number;
if(Int32.TryParse(nvarchar, out number))
{
// etc...
number.ToString();
}
This Regex let you avoid wrong result with digits which consits only from zeroes "0000" and work on digits of any length:
using System.Text.RegularExpressions;
/*
00123 => 123
00000 => 0
00000a => 0a
00001a => 1a
00001a => 1a
0000132423423424565443546546356546454654633333a => 132423423424565443546546356546454654633333a
*/
Regex removeLeadingZeroesReg = new Regex(#"^0+(?=\d)");
var strs = new string[]
{
"00123",
"00000",
"00000a",
"00001a",
"00001a",
"0000132423423424565443546546356546454654633333a",
};
foreach (string str in strs)
{
Debug.Print(string.Format("{0} => {1}", str, removeLeadingZeroesReg.Replace(str, "")));
}
And this regex will remove leading zeroes anywhere inside string:
new Regex(#"(?<!\d)0+(?=\d)");
// "0000123432 d=0 p=002 3?0574 m=600"
// => "123432 d=0 p=2 3?574 m=600"
Regex rx = new Regex(#"^0+(\d+)$");
rx.Replace("0001234", #"$1"); // => "1234"
rx.Replace("0001234000", #"$1"); // => "1234000"
rx.Replace("000", #"$1"); // => "0" (TrimStart will convert this to "")
// usage
var outString = rx.Replace(inputString, #"$1");
I just crafted this as I needed a good, simple way.
If it gets to the final digit, and if it is a zero, it will stay.
You could also use a foreach loop instead for super long strings.
I just replace each leading oldChar with the newChar.
This is great for a problem I just solved, after formatting an int into a string.
/* Like this: */
int counterMax = 1000;
int counter = ...;
string counterString = counter.ToString($"D{counterMax.ToString().Length}");
counterString = RemoveLeadingChars('0', ' ', counterString);
string fullCounter = $"({counterString}/{counterMax})";
// = ( 1/1000) ... ( 430/1000) ... (1000/1000)
static string RemoveLeadingChars(char oldChar, char newChar, char[] chars)
{
string result = "";
bool stop = false;
for (int i = 0; i < chars.Length; i++)
{
if (i == (chars.Length - 1)) stop = true;
if (!stop && chars[i] == oldChar) chars[i] = newChar;
else stop = true;
result += chars[i];
}
return result;
}
static string RemoveLeadingChars(char oldChar, char newChar, string text)
{
return RemoveLeadingChars(oldChar, newChar, text.ToCharArray());
}
I always tend to make my functions suitable for my own library, so there are options.
I have a compressed string value I'm extracting from an import file. I need to format this into a parcel number, which is formatted as follows: ##-##-##-###-###. So therefore, the string "410151000640" should become "41-01-51-000-640". I can do this with the following code:
String.Format("{0:##-##-##-###-###}", Convert.ToInt64("410151000640"));
However, The string may not be all numbers; it could have a letter or two in there, and thus the conversion to the int will fail. Is there a way to do this on a string so every character, regardless of if it is a number or letter, will fit into the format correctly?
Regex.Replace("410151000640", #"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5");
Or the slightly shorter version
Regex.Replace("410151000640", #"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5");
I would approach this by having your own formatting method, as long as you know that the "Parcel Number" always conforms to a specific rule.
public static string FormatParcelNumber(string input)
{
if(input.length != 12)
throw new FormatException("Invalid parcel number. Must be 12 characters");
return String.Format("{0}-{1}-{2}-{3}-{4}",
input.Substring(0,2),
input.Substring(2,2),
input.Substring(4,2),
input.Substring(6,3),
input.Substring(9,3));
}
This should work in your case:
string value = "410151000640";
for( int i = 2; i < value.Length; i+=3){
value = value.Insert( i, "-");
}
Now value contains the string with dashes inserted.
EDIT
I just now saw that you didn't have dashes between every second number all the way, to this will require a small tweak (and makes it a bit more clumsy also I'm afraid)
string value = "410151000640";
for( int i = 2; i < value.Length-1; i+=3){
if( value.Count( c => c == '-') >= 3) i++;
value = value.Insert( i, "-");
}
If its part of UI you can use MaskedTextProvider in System.ComponentModel
MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa");
prov.Set("41x151000a40");
string result = prov.ToDisplayString();
Here is a simple extension method with some utility:
public static string WithMask(this string s, string mask)
{
var slen = Math.Min(s.Length, mask.Length);
var charArray = new char[mask.Length];
var sPos = s.Length - 1;
for (var i = mask.Length - 1; i >= 0 && sPos >= 0;)
if (mask[i] == '#') charArray[i--] = s[sPos--];
else
charArray[i] = mask[i--];
return new string(charArray);
}
Use it as follows:
var s = "276000017812008";
var mask = "###-##-##-##-###-###";
var dashedS = s.WithMask(mask);
You can use it with any string and any character other than # in the mask will be inserted. The mask will work from right to left. You can tweak it to go the other way if you want.
Have fun.
If i understodd you correctly youre looking for a function that removes all letters from a string, aren't you?
I have created this on the fly, maybe you can convert it into c# if it's what you're looking for:
Dim str As String = "410151000vb640"
str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str)))
Public Function MakeNumber(ByVal stringInt As String) As String
Dim sb As New System.Text.StringBuilder
For i As Int32 = 0 To stringInt.Length - 1
If Char.IsDigit(stringInt(i)) Then
sb.Append(stringInt(i))
End If
Next
Return sb.ToString
End Function