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.
Related
I have a string which contains binary digits. How to separate string after each 8 digit?
Suppose the string is:
string x = "111111110000000011111111000000001111111100000000";
I want to add a separator like ,(comma) after each 8 character.
output should be :
"11111111,00000000,11111111,00000000,11111111,00000000,"
Then I want to send it to a list<> last 8 char 1st then the previous 8 chars(excepting ,) and so on.
How can I do this?
Regex.Replace(myString, ".{8}", "$0,");
If you want an array of eight-character strings, then the following is probably easier:
Regex.Split(myString, "(?<=^(.{8})+)");
which will split the string only at points where a multiple of eight characters precede it.
Try this:
var s = "111111110000000011111111000000001111111100000000";
var list = Enumerable
.Range(0, s.Length/8)
.Select(i => s.Substring(i*8, 8));
var res = string.Join(",", list);
There's another Regex approach:
var str = "111111110000000011111111000000001111111100000000";
# for .NET 4
var res = String.Join(",",Regex.Matches(str, #"\d{8}").Cast<Match>());
# for .NET 3.5
var res = String.Join(",", Regex.Matches(str, #"\d{8}")
.OfType<Match>()
.Select(m => m.Value).ToArray());
...or old school:
public static List<string> splitter(string in, out string csv)
{
if (in.length % 8 != 0) throw new ArgumentException("in");
var lst = new List<string>(in/8);
for (int i=0; i < in.length / 8; i++) lst.Add(in.Substring(i*8,8));
csv = string.Join(",", lst); //This we want in input order (I believe)
lst.Reverse(); //As we want list in reverse order (I believe)
return lst;
}
Ugly but less garbage:
private string InsertStrings(string s, int insertEvery, char insert)
{
char[] ins = s.ToCharArray();
int length = s.Length + (s.Length / insertEvery);
if (ins.Length % insertEvery == 0)
{
length--;
}
var outs = new char[length];
long di = 0;
long si = 0;
while (si < s.Length - insertEvery)
{
Array.Copy(ins, si, outs, di, insertEvery);
si += insertEvery;
di += insertEvery;
outs[di] = insert;
di ++;
}
Array.Copy(ins, si, outs, di, ins.Length - si);
return new string(outs);
}
String overload:
private string InsertStrings(string s, int insertEvery, string insert)
{
char[] ins = s.ToCharArray();
char[] inserts = insert.ToCharArray();
int insertLength = inserts.Length;
int length = s.Length + (s.Length / insertEvery) * insert.Length;
if (ins.Length % insertEvery == 0)
{
length -= insert.Length;
}
var outs = new char[length];
long di = 0;
long si = 0;
while (si < s.Length - insertEvery)
{
Array.Copy(ins, si, outs, di, insertEvery);
si += insertEvery;
di += insertEvery;
Array.Copy(inserts, 0, outs, di, insertLength);
di += insertLength;
}
Array.Copy(ins, si, outs, di, ins.Length - si);
return new string(outs);
}
If I understand your last requirement correctly (it's not clear to me if you need the intermediate comma-delimited string or not), you could do this:
var enumerable = "111111110000000011111111000000001111111100000000".Batch(8).Reverse();
By utilizing morelinq.
Here my two little cents too. An implementation using StringBuilder:
public static string AddChunkSeparator (string str, int chunk_len, char separator)
{
if (str == null || str.Length < chunk_len) {
return str;
}
StringBuilder builder = new StringBuilder();
for (var index = 0; index < str.Length; index += chunk_len) {
builder.Append(str, index, chunk_len);
builder.Append(separator);
}
return builder.ToString();
}
You can call it like this:
string data = "111111110000000011111111000000001111111100000000";
string output = AddChunkSeparator(data, 8, ',');
One way using LINQ:
string data = "111111110000000011111111000000001111111100000000";
const int separateOnLength = 8;
string separated = new string(
data.Select((x,i) => i > 0 && i % separateOnLength == 0 ? new [] { ',', x } : new [] { x })
.SelectMany(x => x)
.ToArray()
);
I did it using Pattern & Matcher as following way:
fun addAnyCharacter(input: String, insertion: String, interval: Int): String {
val pattern = Pattern.compile("(.{$interval})", Pattern.DOTALL)
val matcher = pattern.matcher(input)
return matcher.replaceAll("$1$insertion")
}
Where:
input indicates Input string. Check results section.
insertion indicates Insert string between those characters. For example comma (,), start(*), hash(#).
interval indicates at which interval you want to add insertion character.
input indicates Input string. Check results section. Check results section; here I've added insertion at every 4th character.
Results:
I/P: 1234XXXXXXXX5678 O/P: 1234 XXXX XXXX 5678
I/P: 1234567812345678 O/P: 1234 5678 1234 5678
I/P: ABCDEFGHIJKLMNOP O/P: ABCD EFGH IJKL MNOP
Hope this helps.
As of .Net 6, you can simply use the IEnumerable.Chunk method (Which splits elements of a sequence into chunks) then reconcatenate the chunks using String.Join.
var text = "...";
string.Join(',', text.Chunk(size: 6).Select(x => new string(x)));
This is much faster without copying array (this version inserts space every 3 digits but you can adjust it to your needs)
public string GetString(double valueField)
{
char[] ins = valueField.ToString().ToCharArray();
int length = ins.Length + (ins.Length / 3);
if (ins.Length % 3 == 0)
{
length--;
}
char[] outs = new char[length];
int i = length - 1;
int j = ins.Length - 1;
int k = 0;
do
{
if (k == 3)
{
outs[i--] = ' ';
k = 0;
}
else
{
outs[i--] = ins[j--];
k++;
}
}
while (i >= 0);
return new string(outs);
}
For every 1 character, you could do this one-liner:
string.Join(".", "1234".ToArray()) //result: 1.2.3.4
If you intend to create your own function to acheive this without using regex or pattern matching methods, you can create a simple function like this:
String formatString(String key, String seperator, int afterEvery){
String formattedKey = "";
for(int i=0; i<key.length(); i++){
formattedKey += key.substring(i,i+1);
if((i+1)%afterEvery==0)
formattedKey += seperator;
}
if(formattedKey.endsWith("-"))
formattedKey = formattedKey.substring(0,formattedKey.length()-1);
return formattedKey;
}
Calling the mothod like this
formatString("ABCDEFGHIJKLMNOPQRST", "-", 4)
Would result in the return string as this
ABCD-EFGH-IJKL-MNOP-QRST
A little late to the party, but here's a simplified LINQ expression to break an input string x into groups of n separated by another string sep:
string sep = ",";
int n = 8;
string result = String.Join(sep, x.InSetsOf(n).Select(g => new String(g.ToArray())));
A quick rundown of what's happening here:
x is being treated as an IEnumerable<char>, which is where the InSetsOf extension method comes in.
InSetsOf(n) groups characters into an IEnumerable of IEnumerable -- each entry in the outer grouping contains an inner group of n characters.
Inside the Select method, each group of n characters is turned back into a string by using the String() constructor that takes an array of chars.
The result of Select is now an IEnumerable<string>, which is passed into String.Join to interleave the sep string, just like any other example.
I am more than late with my answer but you can use this one:
static string PutLineBreak(string str, int split)
{
for (int a = 1; a <= str.Length; a++)
{
if (a % split == 0)
str = str.Insert(a, "\n");
}
return str;
}
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'm having a problem with modulo from int which has 31 chars. It seems to bug out on
Int64 convertedNumber = Int64.Parse(mergedNumber); with Value was either too large or too small for an Int64. (Overflow Exception). How to fix it so that modulo doesn't bug out ?
class GeneratorRachunkow {
private static string numerRozliczeniowyBanku = "11111155"; // 8 chars
private static string identyfikatorNumeruRachunku = "7244"; // 4 chars
private static string stalaBanku = "562100"; // 6 chars
public static string generator(string pesel, string varKlientID) {
string peselSubstring = pesel.Substring(pesel.Length - 5); // 5 chars (from the end of the string);
string toAttach = varKlientID + peselSubstring;
string indywidualnyNumerRachunku = string.Format("{0}", toAttach.ToString().PadLeft(13, '0')); // merging pesel with klient id and adding 0 to the begining to match 13 chars
string mergedNumber = numerRozliczeniowyBanku + identyfikatorNumeruRachunku + indywidualnyNumerRachunku + stalaBanku; // merging everything -> 31 chars
Int64 convertedNumber = Int64.Parse(mergedNumber);
Int64 modulo = MathMod(convertedNumber, 97);
Int64 wynik = 98 - modulo;
string wynikString = string.Format("{0}", wynik.ToString().PadLeft(2, '0')); // must be 2 chars
indywidualnyNumerRachunku = wynikString + numerRozliczeniowyBanku + identyfikatorNumeruRachunku + indywidualnyNumerRachunku;
return indywidualnyNumerRachunku;
}
private static Int64 MathMod(Int64 a, Int64 b) {
return (Math.Abs(a * b) + a) % b;
}
}
The max value for Int64 is 9223372036854775807 (19 characters when printed). You will probably want to use BigInteger instead (which was introduced in .NET 4):
public static string generator(string pesel, string varKlientID) {
// I have cut some code here to keep it short
BigInteger convertedNumber;
if (BigInteger.TryParse(mergedNumber , out convertedNumber))
{
BigInteger modulo = convertedNumber % 97;
// The rest of the method goes here...
}
else
{
// string could not be parsed to BigInteger; handle gracefully
}
}
private static BigInteger MathMod(BigInteger a, BigInteger b)
{
return (BigInteger.Abs(a * b) + a) % b;
}
Int64.MaxValue is 9,223,372,036,854,775,807 that's 19 characters. So you just can't fit that in. I suggest looking at this question for working with big numbers.
Try this function instead of "MathMod":
static int ModString(string x, int y)
{
if (x.Length == 0)
return 0;
string x2 = x.Substring(0,x.Length - 1); // first digits
int x3 = int.Parse(x.Substring(x.Length - 1)); // last digit
return (ModString(x2, y) * 10 + x3) % y;
}
(since all of your numbers are positive, there is no point in using Math.Abs, as in your original MathMod function).
Use it this way:
modulo = ModString(mergedNumber,97);
This should works with all versions of .NET since 1.1, without the need of BigInteger.
The answer you are looking for is demonstrated here. It includes various manners to calculate the modulus for huge numbers. I used similar methods as described here for international bank account numbers.
A direct link to someone who has a copy pastable method is here.
I was wondering if you could tell me what the most efficient way to repeat a string would be. I need to create a string 33554432 bytes long, repeating the string "hello, world" until it fills that buffer. What is the best way to do it, C is easy in this case:
for (i = 0; i < BIGSTRINGLEN - step; i += step)
memcpy(bigstring+i, *s, step);
Thanks.
An efficient way would be to use a StringBuilder:
string text = "hello, world";
StringBuilder builder = new StringBuilder(BIGSTRINGLEN);
while (builder.Length + text.Length <= BIGSTRINGLEN) {
builder.Append(text);
}
string result = builder.ToString();
First, do you want the string to be 33554432 bytes long, or characters long? .NET and C# use 16-bit characters, so they are not equivalent.
If you want 33554432 characters, naive solution would be string concatenation. See Frédéric Hamidi's answer.
If you want bytes, you will need to do something a bit more interesting:
int targetLength = 33554432;
string filler = "hello, world";
byte[] target = new byte[targetLength];
// Convert filler to bytes. Can use other encodings here.
// I am using ASCII to match C++ output.
byte[] fillerBytes = Encoding.ASCII.GetBytes(filler);
//byte[] fillerBytes = Encoding.Unicode.GetBytes(filler);
//byte[] fillerBytes = Encoding.UTF8.GetBytes(filler);
int position = 0;
while((position + fillerBytes.Length) < target.Length)
{
fillerBytes.CopyTo(target, position);
position += fillerBytes.Length;
}
// At this point, need to possibly do a partial copy.
if (position < target.Length)
{
int bytesNecessary = target.Length - position;
Array.Copy(fillerBytes, 0, target, position, bytesNecessary);
}
I don't know if it's the most efficient way, but if you're using .NET 3.5 or later, this could work:
String.Join("", System.Linq.Enumerable.Repeat("hello, world", 2796203).ToArray()).Substring(0, 33554432);
If the length you want is dynamic, then you can replace some of the hard-coded numbers with simple math.
What about this? Set the StringBuilder to the max expected size and then add the desired string as long as adding another one will not exceed the desired max size.
StringBuilder sb = new StringBuilder(33554432);
int max = sb.MaxCapacity;
String hello = "hello, world";
while (sb.Length + hello.Length <= max)
{
sb.Append(hello);
}
string longString = sb.ToString();
This avoids a loop that repeatedly adds the string. Instead, I "double" the string until it gets close to the right length and then I put the "doubled" pieces together appropriately.
static string Repeat(string s, int length) {
if (length < s.Length) {
return s.Substring(0, length);
}
var list = new List<string>();
StringBuilder t = new StringBuilder(s);
do {
string temp = t.ToString();
list.Add(temp);
t.Append(temp);
} while(t.Length < length);
int index = list.Count - 1;
StringBuilder sb = new StringBuilder(length);
while (sb.Length < length) {
while (list[index].Length > length) {
index--;
}
if (list[index].Length <= length - sb.Length) {
sb.Append(list[index]);
}
else {
sb.Append(list[index].Substring(0, length - sb.Length));
}
}
return sb.ToString();
}
So, for example, on input ("Hello, world!", 64) we build the strings
13: Hello, World!
26: Hello, World!Hello, World!
52: Hello, World!Hello, World!Hello, World!Hello, World!
Then we would build the result by concatenating the string of length 52 to the substring of length 12 of the string of length 13.
I am, of course, assuming that by bytes you meant length. Otherwise, you can easily modify the above using encodings to get what you want in terms of bytes.
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;
}