Place every n-th character in string at n-7 position - c#

I have string with 0's and 1's. It looks like this:
1110011011010000...
With spaces for better visualisation (original string from my program doesn't contain spaces)
11100110 11010000 ...
Every eight elements must be a letter of Unicode in binary.
What i need to do, is put every last 0 or 1 of each letter (every 8th element in full string) to the first place for this letter, so this string would be like this:
0111001101101000...
With spaces for better visualisation (original string from my program doesn't contain spaces)
01110011 01101000 ...
How can I do this in C#?

strings are immutable so i would use StringBuilder to move characters
var s = "1110011011010000";
var window = 8; // the tail of string which is shoreter than 8 symbols (if any) will be ignored
System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
for(int i = 0; i <= s.Length-window; i=i+window)
{
char c = sb[i+window-1];
sb.Remove(i+window-1,1);
sb.Insert(i,c);
}
string result = sb.ToString();

Start by splitting your string into chunks of size eight (here is how).
This gives you an IEnumerable<string>. Take each string of length 8, and recombine its characters like this:
string orig = "11100110";
string res = orig.Substring(1)+orig[0];
Finally, merge back the parts processed in the above way to get your final string (here is how).

Here's my solution. The method ShiftChunkChars takes a string and integer which depicts the amount of characters in each "chunk". Beware that this method does not work if the input string's length is not divisible by chunkSize.
string ShiftChunkChars(string original, int chunkSize)
{
char[] buffer = new char[chunkSize];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < original.Length; i += chunkSize)
{
char[] chars = original.Substring(i, chunkSize).ToCharArray();
Array.Copy(chars, 0, buffer, 1, chunkSize - 1);
buffer[0] = chars[chunkSize - 1];
sb.Append(buffer);
}
return sb.ToString();
}
Examples:
1.
void Main()
{
int chunkSize = 8;
string s = "11100110110100000111001101101000";
ShiftChunkChars(s, chunkSize);
}
Output:
01110011011010001011100100110100
// Original with spaces: 11100110 11010000 01110011 01101000
// Result with spaces: 01110011 01101000 10111001 00110100
2.
void Main()
{
int chunkSize = 4;
string s = "11100110110100000111001101101000";
ShiftChunkChars(s, chunkSize);
}
Output:
01110011111000001011100100110100
// Original with spaces: 1110 0110 1101 0000 0111 0011 0110 1000
// Result with spaces: 0111 0011 1110 0000 1011 1001 0011 0100

You should be able to do this very simple with Regex:
string formattedBinary = Regex.Replace("0111001101101000", ".{8}", "$0 ");

Try with this. Not sure if I have undestood the question. In this case I looped twice because I had 16 chars.
string s = "1110011011010000";
char[] nc = s.ToCharArray();
for (int i = 0; i < 2; i++)
{
char tmp = nc[i * 8 + 7];
for (int j = 6; j > 0; j--)
{
nc[i * 8 + j + 1] = nc[i * 8 + j];
}
nc[i * 8] = tmp;
}
s = new string(nc);

Related

C# How convert unHex to String

I'm trying to convert an unHex value to a string but it's not working.
I have the following value 0x01BB92E7F716F55B144768FCB2EA40187AE6CF6B2E52A64F7331D0539507441F7D770112510D679F0B310116B0D709E049A19467672FFA532A7C30DFB72
Result I hope would be this
but executing the function below displays this result
»’ Ç ÷ õ [Ghü²ê # zæÏk.R¦Os1ÐS • D} w Q gŸ 1 ° × àI¡ ”gg / úS * | 0ß ·) = ¤
Any idea how I can extract the information as expected
public static string Hex2String (string input)
{
var builder = new StringBuilder ();
for (int i = 0; i < socketLength; i + = 2)
{
// throws an exception if not properly formatted
string hexdec = input.Substring (i, 2);
int number = Int32.Parse (hexdec, NumberStyles.HexNumber);
char charToAdd = (char) number;
builder.Append (charToAdd);
}
return builder.ToString ();
}
Your result is base64-encoded. Base64 is a way of taking a byte array and turning it into human-readable characters.
Your code tries to take these raw bytes and cast them to chars, but not all byte values are valid printable characters: some are control characters, some can't be printed, etc.
Instead, let's turn the hex string into a byte array, and then turn that byte array into a base64 string.
string input = "01BB92E7F716F55B144768FCB2EA40187AE6CF6B2E52A64F7331D0539507441F7D770112510D679F0B310116B0D709E049A19467672FFA532A7C30DFB72";
byte[] bytes = new byte[input.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = byte.Parse(input.Substring(i * 2, 2), NumberStyles.HexNumber);
}
string result = Convert.ToBase64String(bytes);
This results in:
AbuS5/cW9VsUR2j8supAGHrmz2suUqZPczHQU5UHRB99dwESUQ1nnwsxARaw1wngSaGUZ2cv+lMqfDDftw==
See it running here.

Xor operation between binary values in C#

My question is that i have a list of binary string like below :
list=<"1111","1010","1010","0011">
and an input string of binary value st1=1010. I want to Xor between :
st3=st1 Xor list<0>
then :
st3=st3 Xor list<1>
st3=st3Xor list <2>;
st3=st3 Xor list <3>;
where the operation will be st1 Xor with first key in keys list and the result Xor with the second key in keys list and the result Xor with the third key in keys list and so on . Can any one help me please?
i have tried this code but it does not work as i expected :
foreach (string k in keys)
{
string st1 = textBox1.text;
string st2 = k;
string st3;
st3 = "";
//i wanted to make the length of both strings st1 and st2 equal
//here if the length of st1 greater than st2
if (st1.Length > st2.Length)
{
int n = st1.Length - st2.Length;
string pad = "";
for (int j = 1; j <= n; j++)
{ pad += 0; }
string recover = pad.ToString() + st2;
//this is my Xor operation that i made for string values
for (int counter = 0; counter < st1.Length; counter++)
{
if (st1[counter] != recover[counter])
{
st3 = st3 + '1';
}
else
{ st3 = st3 + '0'; }
}
listBox4.Items.Add("Xor :" + st3.ToString());
}
//here if st1 is less than st2
else if (st1.Length < st2.Length)
{
int nn = st2.Length - st1.Length;
string ppad = "";
for (int j = 1; j <= nn; j++)
{
ppad += 0;
}
string recover = ppad.ToString() + st1;
for (int counter = 0; counter < st2.Length; counter++)
{
if (st2[counter] != recover[counter])
{
st3 = st3 + '1';
}
else
{ st3 = st3 + '0'; }
}
listBox4.Items.Add("Xor :" + st3.ToString());}
//here if st1 equal st2
else
{
for (int counter = 0; counter < st1.Length; counter++)
{
if (st1[counter] != st2[counter])
{
st3 = st3 + '1';
}
else
{ st3 = st3 + '0'; }
}
listBox4.Items.Add("Xor :" + st3.ToString());
}
}
the result that i do not expected is :
Here's one approach (Arbitrary length binary strings):
Convert the strings back to integers BigIntegers, so that we can actually get the utility of existing bitwise Xor operator (^).
Use LINQ's Aggregate to consecutively left-fold the seed value (st1) with the converted list with Xor.
Since you seem interested only in the lowest 4 bits, I've applied a mask, although if all your numbers are strictly 4 bits, this isn't actually necessary (since 0 Xor 0 stays 0)
You can convert the int back to a binary string with Convert.ToString(x, 2) and then PadLeft to replace any missing leading zeroes.
Edit - OP has changed the question from an example 4 bit number and the requirement is now to work with arbitrary length binary strings. This approach still works, but we'll need to use BigInteger (which still has an XOR ^ operator), but we need helpers to parse and format binary strings, as these aren't built into BigInteger. The BitMask and padding have also been removed, since the strings aren't fixed length - the result will have at most 1 leading zero:
var list = new List<string>{"10101010101010101101","1101010101010101011",
"1110111111010101101","11111111111111111111111111","10101010110101010101"};
var listNum = list.Select(l => BinaryStringToBigInteger(l));
var st1 = "000000001";
var seedNumber = BinaryStringToBigInteger(st1);
var chainedXors = listNum.Aggregate(seedNumber, (prev, next) => prev ^ next);
// Back to binary representation of the string
var resultString = chainedXors.ToBinaryString();
And because there's no native support for converting BigIntegers to / from binary strings, you'll need a conversion helper such as Douglas's one here:
BigInteger BinaryStringToBigInteger(string binString)
{
return binString.Aggregate(BigInteger.Zero, (prev, next) => prev * 2 + next - '0');
}
And for the reverse operation, ToBinaryString is from this helper.
32 Bit Integer answer
If the Binary strings are 32 bits or less, then a much simpler solution exists, since there are out of the box conversions to / from binary strings. The same approach should apply for 64 bit longs.
var list = new List<string>{"1111","1010","1010","0011","0011"};
var listNum = list.Select(l => Convert.ToInt32(l, 2));
// If you only want the last 4 bits. Change this to include as many bits as needed.
var bitMask = Convert.ToInt32("00000000000000000000000000001111", 2);
var st1 = "1010";
var someNum = Convert.ToInt32(st1, 2);
var chainedXors = listNum.Aggregate(someNum, (prev, next) => prev ^ next);
// If you need the result back as a 4 bit binary-string, zero padded
var resultString = Convert.ToString(chainedXors & bitMask, 2)
.PadLeft(4, '0');
Try this code:
static void Main(string[] args)
{
List<string> list = new List<string> { "1111", "1010", "1010", "0011" };
string st1 = "1010";
foreach (string item in list)
{
st1 = XorBins(st1, item);
Console.WriteLine(st1);
}
Console.ReadKey();
}
private static string XorBins(string bin1, string bin2)
{
int len = Math.Max(bin1.Length, bin2.Length);
string res = "";
bin1 = bin1.PadLeft(len, '0');
bin2 = bin2.PadLeft(len, '0');
for (int i = 0; i < len; i++)
res += bin1[i] == bin2[i] ? '0' : '1';
return res;
}
Here is an Xor method for you:
public static string Xor(string s1, string s2) {
// find the length of the longest of the two strings
int longest = Math.Max(s1.Length, s2.Length);
// pad both strings to that length. You don't need to write the padding
// logic yourself! There is already a method that does that!
string first = s1.PadLeft(longest, '0');
string second = s2.PadLeft(longest, '0');
// Enumerable.Zip takes two sequences (in this case sequences of char, aka strings)
// and lets you transform each element in the sequences. Here what
// I did was check if the two chars are not equal, in which case
// I transform the two elements to a 1, 0 otherwise
return string.Join("", Enumerable.Zip(first, second, (x, y) => x != y ? '1' : '0'));
}
You can use it like this:
Xor("1111", "1010") // 0101

Find all possible combinations of word with and without hyphens

For a string that may have zero or more hyphens in it, I need to extract all the different possibilities with and without hyphens.
For example, the string "A-B" would result in "A-B" and "AB" (two possibilities).
The string "A-B-C" would result in "A-B-C", "AB-C", "A-BC" and "ABC" (four possibilities).
The string "A-B-C-D" would result in "A-B-C-D", "AB-C-D", "A-BC-D", "A-B-CD", "AB-CD", "ABC-D", "A-BCD" and "ABCD" (eight possibilities).
...etc, etc.
I've experimented with some nested loops but haven't been able to get anywhere near the desired result. I suspect I need something recursive unless there is some simple solution I am overlooking.
NB. This is to build a SQL query (shame that SQL Server does't have MySQL's REGEXP pattern matching).
Here is one attempt I was working on. This might work if I do this recursively.
string keyword = "A-B-C-D";
List<int> hyphens = new List<int>();
int pos = keyword.IndexOf('-');
while (pos != -1)
{
hyphens.Add(pos);
pos = keyword.IndexOf('-', pos + 1);
}
for (int i = 0; i < hyphens.Count(); i++)
{
string result = keyword.Substring(0, hyphens[i]) + keyword.Substring(hyphens[i] + 1);
Response.Write("<p>" + result);
}
A B C D are words of varying length.
Take a look at your sample cases. Have you noticed a pattern?
With 1 hyphen there are 2 possibilities.
With 2 hyphens there are 4 possibilities.
With 3 hyphens there are 8 possibilities.
The number of possibilities is 2n.
This is literally exponential growth, so if there are too many hyphens in the string, it will quickly become infeasible to print them all. (With just 30 hyphens there are over a billion combinations!)
That said, for smaller numbers of hyphens it might be interesting to generate a list. To do this, you can think of each hyphen as a bit in a binary number. If the bit is 1, the hyphen is present, otherwise it is not. So this suggests a fairly straightforward solution:
Split the original string on the hyphens
Let n = the number of hyphens
Count from 2n - 1 down to 0. Treat this counter as a bitmask.
For each count begin building a string starting with the first part.
Concatenate each of the remaining parts to the string in order, preceded by a hyphen only if the corresponding bit in the bitmask is set.
Add the resulting string to the output and continue until the counter is exhausted.
Translated to code we have:
public static IEnumerable<string> EnumerateHyphenatedStrings(string s)
{
string[] parts = s.Split('-');
int n = parts.Length - 1;
if (n > 30) throw new Exception("too many hyphens");
for (int m = (1 << n) - 1; m >= 0; m--)
{
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i <= n; i++)
{
if ((m & (1 << (i - 1))) > 0) sb.Append('-');
sb.Append(parts[i]);
}
yield return sb.ToString();
}
}
Fiddle: https://dotnetfiddle.net/ne3N8f
You should be able to track each hyphen position, and basically say its either there or not there. Loop through all the combinations, and you got all your strings. I found the easiest way to track it was using a binary, since its easy to add those with Convert.ToInt32
I came up with this:
string keyword = "A-B-C-D";
string[] keywordSplit = keyword.Split('-');
int combinations = Convert.ToInt32(Math.Pow(2.0, keywordSplit.Length - 1.0));
List<string> results = new List<string>();
for (int j = 0; j < combinations; j++)
{
string result = "";
string hyphenAdded = Convert.ToString(j, 2).PadLeft(keywordSplit.Length - 1, '0');
// Generate string
for (int i = 0; i < keywordSplit.Length; i++)
{
result += keywordSplit[i] +
((i < keywordSplit.Length - 1) && (hyphenAdded[i].Equals('1')) ? "-" : "");
}
results.Add(result);
}
This works for me:
Func<IEnumerable<string>, IEnumerable<string>> expand = null;
expand = xs =>
{
if (xs != null && xs.Any())
{
var head = xs.First();
if (xs.Skip(1).Any())
{
return expand(xs.Skip(1)).SelectMany(tail => new []
{
head + tail,
head + "-" + tail
});
}
else
{
return new [] { head };
}
}
else
{
return Enumerable.Empty<string>();
}
};
var keyword = "A-B-C-D";
var parts = keyword.Split('-');
var results = expand(parts);
I get:
ABCD
A-BCD
AB-CD
A-B-CD
ABC-D
A-BC-D
AB-C-D
A-B-C-D
I've tested this code and it is working as specified in the question. I stored the strings in a List<string>.
string str = "AB-C-D-EF-G-HI";
string[] splitted = str.Split('-');
List<string> finalList = new List<string>();
string temp = "";
for (int i = 0; i < splitted.Length; i++)
{
temp += splitted[i];
}
finalList.Add(temp);
temp = "";
for (int diff = 0; diff < splitted.Length-1; diff++)
{
for (int start = 1, limit = start + diff; limit < splitted.Length; start++, limit++)
{
int i = 0;
while (i < start)
{
temp += splitted[i++];
}
while (i <= limit)
{
temp += "-";
temp += splitted[i++];
}
while (i < splitted.Length)
{
temp += splitted[i++];
}
finalList.Add(temp);
temp = "";
}
}
I'm not sure your question is entirely well defined (i.e. could you have something like A-BCD-EF-G-H?). For "fully" hyphenated strings (A-B-C-D-...-Z), something like this should do:
string toParse = "A-B-C-D";
char[] toParseChars = toPase.toCharArray();
string result = "";
string binary;
for(int i = 0; i < (int)Math.pow(2, toParse.Length/2); i++) { // Number of subsets of an n-elt set is 2^n
binary = Convert.ToString(i, 2);
while (binary.Length < toParse.Length/2) {
binary = "0" + binary;
}
char[] binChars = binary.ToCharArray();
for (int k = 0; k < binChars.Length; k++) {
result += toParseChars[k*2].ToString();
if (binChars[k] == '1') {
result += "-";
}
}
result += toParseChars[toParseChars.Length-1];
Console.WriteLine(result);
}
The idea here is that we want to create a binary word for each possible hyphen. So, if we have A-B-C-D (three hyphens), we create binary words 000, 001, 010, 011, 100, 101, 110, and 111. Note that if we have n hyphens, we need 2^n binary words.
Then each word maps to the output you desire by inserting the hyphen where we have a '1' in our word (000 -> ABCD, 001 -> ABC-D, 010 -> AB-CD, etc). I didn't test the code above, but this is at least one way to solve the problem for fully hyphenated words.
Disclaimer: I didn't actually test the code

Convert an integer to a binary string with leading zeros

I need to convert int to bin and with extra bits.
string aaa = Convert.ToString(3, 2);
it returns 11, but I need 0011, or 00000011.
How is it done?
11 is binary representation of 3. The binary representation of this value is 2 bits.
3 = 20 * 1 + 21 * 1
You can use String.PadLeft(Int, Char) method to add these zeros.
// convert number 3 to binary string.
// And pad '0' to the left until string will be not less then 4 characters
Convert.ToString(3, 2).PadLeft(4, '0') // 0011
Convert.ToString(3, 2).PadLeft(8, '0') // 00000011
I've created a method to dynamically write leading zeroes
public static string ToBinary(int myValue)
{
string binVal = Convert.ToString(myValue, 2);
int bits = 0;
int bitblock = 4;
for (int i = 0; i < binVal.Length; i = i + bitblock)
{ bits += bitblock; }
return binVal.PadLeft(bits, '0');
}
At first we convert my value to binary.
Initializing the bits to set the length for binary output.
One Bitblock has 4 Digits. In for-loop we check the length of our converted binary value und adds the "bits" for the length for binary output.
Examples:
Input: 1 -> 0001;
Input: 127 -> 01111111
etc....
You can use these methods:
public static class BinaryExt
{
public static string ToBinary(this int number, int bitsLength = 32)
{
return NumberToBinary(number, bitsLength);
}
public static string NumberToBinary(int number, int bitsLength = 32)
{
string result = Convert.ToString(number, 2).PadLeft(bitsLength, '0');
return result;
}
public static int FromBinaryToInt(this string binary)
{
return BinaryToInt(binary);
}
public static int BinaryToInt(string binary)
{
return Convert.ToInt32(binary, 2);
}
}
Sample:
int number = 3;
string byte3 = number.ToBinary(8); // output: 00000011
string bits32 = BinaryExt.NumberToBinary(3); // output: 00000000000000000000000000000011
public static String HexToBinString(this String value)
{
String binaryString = Convert.ToString(Convert.ToInt32(value, 16), 2);
Int32 zeroCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(binaryString.Length) / 8)) * 8;
return binaryString.PadLeft(zeroCount, '0');
}
Just what Soner answered use:
Convert.ToString(3, 2).PadLeft(4, '0')
Just want to add just for you to know. The int parameter is the total number of characters that your string and the char parameter is the character that will be added to fill the lacking space in your string. In your example, you want the output 0011 which which is 4 characters and needs 0's thus you use 4 as int param and '0' in char.
string aaa = Convert.ToString(3, 2).PadLeft(10, '0');
This may not be the most elegant solution but it is the fastest from my testing:
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string LongToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(long) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((ulong)value << (n + diff))) >> (sizeof(long) * 8 - 1)));
}
return new string(output);
}
This version completely avoids if statements and therfore branching which creates very fast and most importantly linear code. This beats the Convert.ToString() function from microsoft by up to 50%
Here is some benchmark code
long testConv(Func<int, int, string> fun, int value, int digits, long avg) {
long result = 0;
for (long n = 0; n < avg; n++) {
var sw = Stopwatch.StartNew();
fun(value, digits);
result += sw.ElapsedTicks;
}
Console.WriteLine((string)fun(value, digits));
return result / (avg / 100);//for bigger output values
}
string IntToBinary(int value, int totalDigits) {
char[] output = new char[totalDigits];
int diff = sizeof(int) * 8 - totalDigits;
for (int n = 0; n != totalDigits; ++n) {
output[n] = (char)('0' + (char)((((uint)value << (n + diff))) >> (sizeof(int) * 8 - 1)));
}
return new string(output);
}
string Microsoft(int value, int totalDigits) {
return Convert.ToString(value, toBase: 2).PadLeft(totalDigits, '0');
}
int v = 123, it = 10000000;
Console.WriteLine(testConv(Microsoft, v, 10, it));
Console.WriteLine(testConv(IntToBinary, v, 10, it));
Here are my results
0001111011
122
0001111011
75
Microsofts Method takes 1.22 ticks while mine only takes 0.75 ticks
With this you can get binary representation of string with corresponding leading zeros.
string binaryString = Convert.ToString(3, 2);;
int myOffset = 4;
string modified = binaryString.PadLeft(binaryString.Length % myOffset == 0 ? binaryString.Length : binaryString.Length + (myOffset - binaryString.Length % myOffset), '0'));
In your case modified string will be 0011, if you want you can change offset to 8, for instance, and you will get 00000011 and so on.

Appending sequential characters to StringBuilder [duplicate]

This question already has answers here:
How to convert a column number (e.g. 127) into an Excel column (e.g. AA)
(60 answers)
Closed 9 years ago.
I am trying to append sequential characters: A, B, ... AA, AB, ... to the beginning a a stringbuilder type. The problem I am having is that it will append all ASCII characters and not double characters. My code looks like this:
string prefix = null;
System.Text.StringBuilder text = new System.Text.StringBuilder();
for (j = 0; j < genList.Count; j++)
{
prefix = "." + Convert.ToChart(j + 65).ToString();
text.Append(prefix + genList[j]);
}
What you really want is something that will output an integer in base-26, using the letters A through Z as digits. So 0 corresponds to A, 25 is Z, 26 is AA, etc.
const string digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string ToBase26(int i)
{
StringBuilder sb = new StringBuilder();
do
{
sb.Append(digits[i % 26]);
i /= 26;
} while (i != 0);
// The digits are backwards. Reverse them.
return new string(sb.ToString.Reverse());
}
That's not the most optimum way to do it, but it'll work.
To output A, B, C, ... AA, AB, AC ... BA, etc:
for (int i = 0; i < Count; ++i)
{
Console.WriteLine(ToBase26(i));
}

Categories

Resources