Reverse a foreach loop action - c#

I want to convert/find each of my string characters to (int) and reverse this operation.
I manage to do the first part,but the seconds one is giving me some problems.
string input;
string encrypt = ""; string decrypt = "";
input = textBox.Text;
foreach (char c in input)
{
int x = (int)c;
string s = x.ToString();
encrypt += s;
}
MessageBox.Show(encrypt);
foreach (int i in encrypt)
{
char c = (char)i;
string s = c.ToString();
decrypt += c;
}
MessageBox.Show(decrypt);
Thanks!

Here is a fixed program according to my advise above
string encrypt = ""; string decrypt = "";
string input = Console.ReadLine();
var length = input.Length;
int[] converted = new int[length];
for (int index = 0; index < length; index++)
{
int x = input[index];
string s = x.ToString();
encrypt += s;
converted[index] = x;
}
Console.WriteLine(encrypt);
for (int index = 0; index < converted.Length; index++)
{
char c = (char)converted[index];
string s = c.ToString();
decrypt += s;
}
Console.WriteLine(decrypt);

This will not work as is, because you're adding numbers to a string with no padding.
Let's assume the first three letter's values are '1','2','3', you'll have a string with "123".
Now, if you know each letter is 1 int length, you're good, but what happens if 12 is valid? and 23?
This might not be a "real" issues in your case because the values will probably be all 2 ints long, but it's very lacking (unless it's homework, in which case, oh well ...)
The ascii values for the alphabet will go from 65 for A to 122 z.
You can either pad them (say 3 chars per number, so 065 for A, and so on), delimit them (have ".", and split the string on that), use an array (like shahar's suggestion), lists, etc etc ...

In Your scenario, encryption may give output as you expected but its hard to decrypt the encrypted text using such mechanism. so I just do some customization on your code and make it workable here.
i suggest a similar one here:
string input;
string encrypt = ""; string decrypt = "";
int charCount = 0;
input = "textBox.Text";
foreach (char c in input)
{
int x = (int)c;
string s = x.ToString("000");
encrypt += s;
charCount++;
}
// MessageBox.Show(encrypt);
while (encrypt.Length > 0)
{
int item = Int32.Parse(encrypt.Substring(0, 3));
encrypt = encrypt.Substring(3);
char c = (char)item;
string s = c.ToString();
decrypt += c;
}
Reason for your code is not working:
You have declared encrypt as string and iterate through each integer in that string value, it is quiet not possible.
if you make that loop to iterate through each characters in that string value again it gives confusion. as :
lets take S as your input. its equivalent int value is 114 so if you make a looping means it will give 1,1,4, you will not get s back from it.

Related

repeating the Encrypt function along the length of the bina function

I want to repeat the Encrypt function along the entire length of the bina / how to do it?
private void carbonFiberButton11_Click_1(object sender, EventArgs e)
{
textBox1.Text = PairConcat(Encrypt(), bina());
}
public static string PairConcat(string Encrypt, string bina)
{
StringBuilder result = new StringBuilder();
int i = 0;
for(; i<Encrypt.Length & i < bina.Length; i++)
{
result.Append(Encrypt[i].ToString());
result.Append(bina[i].ToString());
}
result.Append(Encrypt.Substring(i));
result.Append(bina.Substring(i));
return result.ToString();
}
For example:
string bina = "1234567";
string Encrypt = "abcdefg";
textbox1.text = 1a2b3c4d.. ;but it is doesn't works if I have different length:
string bina = "12345"
string Encrypt = "abc"
textbox1.text = 1a2b3c45 , but I need - 1a2b3c4a5b.
Encrypt function:
string Encrypt() //random to binary
{
var encrypt = textBox4.Text;
StringBuilder binary = new StringBuilder();
for (int i = 0; i < encrypt.Length; i++)
{
binary.Append(Convert.ToString(encrypt[i], 2).PadLeft(8, '0'));
}
return binary.ToString();
}
I can't understand what to do/ Help me, please
Just make the Encrypt string in minimum as long as the bina string.
// Calculate smallest multiple of Encrypt.Length at least as long as bina.Length
int lb = bina.Length;
int le = Encrypt.Length;
int bufferLength = (lb + le - 1) / le * le;
var sb = new StringBuilder(Encrypt, bufferLength);
while (sb.Length < lb) {
sb.Append(Encrypt);
}
Encrypt = sb.ToString();
string result = String.Join("", bina.Zip(Encrypt, (a, b) => a.ToString() + b));
The LINQ Zip method combines 2 sequences by providing pairs of items from the two sequences until one sequence ends. Here the sequences consist of chars.
The StringBuilder works most efficiently if does not have to resize its internal buffer. I calculate it by using integer arithmetic.

Counting number of char in a string and creating another string with the same number of char

So I want to be able to create a headline and underline it with for example an "=". However I want the number of "=" to match with the number of characters in the headline. Preferably I want to be able to do it with a for loop.
Here's what I have so far.
string headLine = "Example";
Console.WriteLine(headLine);
for (char i = '='; i <= headLine.Length; i += '=')
{
Console.WriteLine(i);
}
No need for any loops, just create a new string to your specifications:
string headLine = "Example";
Console.WriteLine(headLine);
Console.WriteLine(new string('=', headLine.Length));
your for loop is completely wrong, you are comparing a char which represents value with an int that represents length. Do something like this instead:
string headLine = "Example";
Console.WriteLine(headLine);
char c = '=';
for (int i=0; i < headLine.Length; i++) //from 0 to length-1 gives the full length
{
Console.Write(c);
}

c# switch all letters in a string for a different pre-chosen letter

Whilst working on a simple project I was trying to come up with a very basic cryptographic system which will allow me to switch letters in a message to another pre-chosen letter. So far I have tried a few ways but have so far been unsuccessful in my attempts. (*NOTE: This is not for anything other then learning the basics of c# so randomness and security is not important in this case, I simply want to turn one letter into another for the sake of learning how to do it)
so first I started by defining some strings such as this
string a = "a";
string b = "b";
string c = "d";
..... //continues to string z = "z"
next I tried to create a new string based on the values that have been input in to a textbox called PlainTextBox and place them inside a separate textbox called ChangedTextBox. this code is triggered with a button click event.
string str = PlainTextBox.Text;
char[] array = str.ToCharArray();
array[int.Parse(a)] = 'x';
array[int.Parse(b)] = 'y';
array[int.Parse(c)] = 'z';
.......// continues to (z)
str = new string(array);
ChangedTextBox.Text = str;
but this code throws an exception because the input is not a valid integer. the basic Idea is that if the user types "abc" in the PlainTextBox and pushes a button, the ChangedTextBox should show "xyz" but should be inclusive of the whole text in PlainTextBox, switching every letter in the message to its chosen counterpart.
Besides the error I receive, this code seems very cumbersome and inefficient.
Is there a faster way to achieve this result?
Just for completeness I will also include information, that what you are doing is called Caesar cipher
You could define yourself a proper Dictionary
var mapping = new Dictionary<char, char>()
{
{ 'a', 'x' },
{ 'b', 'y' },
{ 'c', 'z' }
// other letters
}
in which you would assign every original letter the letter it should be converted to. Then you could use this dictionary
ChangedTextBox.Text = new string(PlainTextBox.Text.Select(letter => mapping[letter].ToArray());
You've chosen wrong collection type (array) for mapping; dictionary is much more convenient
private static Dictionary<char, char> m_Mapping = new Dictionary<char, char>() {
{'a', 'x'}, // a -> x
{'b', 'y'}, // b -> y
...
};
Then implement the encoding
// I'd rather used Linq
private static String Encode(String value) {
// Simplest: we don't check if the actual character can be mapped
return String.Concat(value.Select(c => m_Mapping[c]));
}
But your (amended) implementation is good enough:
private static String Encode(string str) {
char[] array = str.ToCharArray();
for (int i = 0; i < array.Length; ++i) {
// Simplest: we don't check if the actual character can be mapped
array[i] = m_Mapping[array[i]];
}
return new string(array);
}
Finally, add up UI:
ChangedTextBox.Text = Encode(PlainTextBox.Text);
Edit: in general case, when m_Mapping doesn't contain records for some characters (e.g. for new line \n) and so we want to preserve these characters intact we can't use direct m_Mapping[...] but should implement, say, EncodeChar.
private static char EncodeChar(char value) {
char result;
if (m_Mapping.TryGetValue(value, out result))
return result;
else
return value;
}
And put EncodeChar(...) instead of m_Mapping[...]
private static String Encode(String value) {
return String.Concat(value.Select(EncodeChar(c)));
}
Your version
private static String Encode(string str) {
char[] array = str.ToCharArray();
for (int i = 0; i < array.Length; ++i) {
array[i] = EncodeChar(array[i]);
return new string(array);
}
Probably the best solution is using a Dictionary, as other answers had said. But if I understand what you want, you want to just change one letter by that letter plus an offset in a kind of "circular" way. This solution would do something like that (with "abcd" as input it would return "xyza"):
string input = "abcd";
char startChar = 'x';
char lastChar = 'z';
char firstChar = 'a';
byte[] asciiBytes=Encoding.ASCII.GetBytes(input);
byte[] encriptedByteArray = new byte[asciiBytes.Length];
int val = (int)startChar-(int)firstChar;
int i = 0;
foreach(byte b in asciiBytes)
{
var a=b + val;
if (a>(int)lastChar)
{
a = firstChar+(a-lastChar)-1;
}
encriptedByteArray[i] = (byte)a;
i++;
}
string encriptedArray = System.Text.Encoding.UTF8.GetString(encriptedByteArray);
With this solution you can change the offsety easily (changing startChar). It has room for improvement though, for example it only works on lower letters from a-z, it could be changed to be more extensive.
int.Parse(a)
will of course throw InvalidCastException because a is a string as you've defined it
string a = "a";

Calculate number of zeros in a string

I have a string as follow 51200000000000000000000000000000
This string is not fixed. It will be appended depends on the number of boards. If there are two boards, the string will be as follow 5120000000000000000000000000000052200000000000000000000000000000
I would like to know how to calculate the number of zeros in the string.
I'm using the following code but it is not flexible if there are more than two boards.
string str = "51200000000000000000000000000000";
string zeros = "00000000000000000000000000000";
if (str.Contains(zeros))
{
Console.WriteLine("true");
}
else
{
Console.WriteLine("false");
}
You can use the following piece of code to do this, which will give you the number of zeros(Example).
char matchChar='0';
string strInput = "51200000000000000000000000000000";
int zeroCount = strInput.Count(x => x == matchChar); // will be 29
You can do the same by iterating through each characters and check whether it is the required character(say 0) then take its count.
Use a simple foreach loop to traverse the string and count:
int CountZeroes(string str)
{
// TODO: error checking, etc.
int count = 0;
foreach (var character in str)
{
if (character == '0') count++;
}
return count;
}
a little advanced (or so) technique would be to convert the string to char array then to list of chars then using LINQ
string str = "51200000000000000000000000000000";
List<char> nums = str.ToCharArray().ToList();
Console.WriteLine(nums.Where(x => x.Equals('0')).Select(x => x.ToString()).Count());
i just placed this here in case you want to learn not just a single approach :)
It can also do with a for loop and Substring.
Code
string str = "51200000000000000000000000000000";
int n = 0;
for (int i = 0; i < str.Length; i++)
{
if (str.Substring(i, 1) == "0")
n += 1;
}
Console.WriteLine("Count : " + n.ToString());
Working fiddle demo
Code:
string st;
st = textBox1.Text;
int countch = 0, i;
for (i = 0; i < st.Length; i++)
if (st[i]=='0') countch++;
MessageBox.Show(countch.ToString());
using System.Linq
int count0s = str.Count(z => z == '0');
will return how many 0's in your str string

string values to byte array without converting

I'm trying to put the values of a string into a byte array with out changing the characters. This is because the string is in fact a byte representation of the data.
The goal is to move the input string into a byte array and then convert the byte array using:
string result = System.Text.Encoding.UTF8.GetString(data);
I hope someone can help me although I know it´s not a very good description.
EDIT:
And maybe I should explain that what I´m working on is a simple windows form with a textbox where users can copy the encoded data into it and then click preview to see the decoded data.
EDIT:
A little more code:
(inputText is a textbox)
private void button1_Click(object sender, EventArgs e)
{
string inputString = this.inputText.Text;
byte[] input = new byte[inputString.Length];
for (int i = 0; i < inputString.Length; i++)
{
input[i] = inputString[i];
}
string output = base64Decode(input);
this.inputText.Text = "";
this.inputText.Text = output;
}
This is a part of a windows form and it includes a rich text box. This code doesn´t work because it won´t let me convert type char to byte.
But if I change the line to :
private void button1_Click(object sender, EventArgs e)
{
string inputString = this.inputText.Text;
byte[] input = new byte[inputString.Length];
for (int i = 0; i < inputString.Length; i++)
{
input[i] = (byte)inputString[i];
}
string output = base64Decode(input);
this.inputText.Text = "";
this.inputText.Text = output;
}
It encodes the value and I don´t want that. I hope this explains a little bit better what I´m trying to do.
EDIT: The base64Decode function:
public string base64Decode(byte[] data)
{
try
{
string result = System.Text.Encoding.UTF8.GetString(data);
return result;
}
catch (Exception e)
{
throw new Exception("Error in base64Decode" + e.Message);
}
}
The string is not encoded using base64 just to be clear. This is just bad naming on my behalf.
Note this is just one line of input.
I've got it. The problem was I was always trying to decode the wrong format. I feel very stupid because when I posted the example input I saw this had to be hex and it was so from then on it was easy. I used this site for reference:
http://msdn.microsoft.com/en-us/library/bb311038.aspx
My code:
public string[] getHexValues(string s)
{
int j = 0;
string[] hex = new String[s.Length/2];
for (int i = 0; i < s.Length-2; i += 2)
{
string temp = s.Substring(i, 2);
this.inputText.Text = temp;
if (temp.Equals("0x")) ;
else
{
hex[j] = temp;
j++;
}
}
return hex;
}
public string convertFromHex(string[] hex)
{
string result = null;
for (int i = 0; i < hex.Length; i++)
{
int value = Convert.ToInt32(hex[i], 16);
result += Char.ConvertFromUtf32(value);
}
return result;
}
I feel quite dumb right now but thanks to everyone who helped, especially #Jon Skeet.
Are you saying you have something like this:
string s = "48656c6c6f2c20776f726c6421";
and you want these values as a byte array? Then:
public IEnumerable<byte> GetBytesFromByteString(string s) {
for (int index = 0; index < s.Length; index += 2) {
yield return Convert.ToByte(s.Substring(index, 2), 16);
}
}
Usage:
string s = "48656c6c6f2c20776f726c6421";
var bytes = GetBytesFromByteString(s).ToArray();
Note that the output of
Console.WriteLine(System.Text.ASCIIEncoding.ASCII.GetString(bytes));
is
Hello, world!
You obviously need to make the above method a lot safer.
Encoding has the reverse method:
byte[] data = System.Text.Encoding.UTF8.GetBytes(originalString);
string result = System.Text.Encoding.UTF8.GetString(data);
Debug.Assert(result == originalString);
But what you mean 'without converting' is unclear.
One way to do it would be to write:
string s = new string(bytes.Select(x => (char)c).ToArray());
That will give you a string that has one character for every single byte in the array.
Another way is to use an 8-bit character encoding. For example:
var MyEncoding = Encoding.GetEncoding("windows-1252");
string s = MyEncoding.GetString(bytes);
I'm think that Windows-1252 defines all 256 characters, although I'm not certain. If it doesn't, you're going to end up with converted characters. You should be able to find an 8-bit encoding that will do this without any conversion. But you're probably better off using the byte-to-character loop above.
If anyone still needs it this worked for me:
byte[] result = Convert.FromBase64String(str);
Have you tried:
string s = "....";
System.Text.UTF8Encoding.UTF8.GetBytes(s);

Categories

Resources