I am a beginner learning c#.
I have coded a method that turns a two digit integer in a sequence of 16 bits
// takes input from user and convert it
private void Button_Click(object sender, RoutedEventArgs e)
{
string input = key.Text;
string mykey = "";
foreach (var item in input)
{
mykey += Binary(item);
}
key.Text = mykey;
}
private string Binary(Char ch)
{
string result = string.Empty;
int asciiCode;
char[] bits = new char[8];
asciiCode = (int)ch;
result = Convert.ToString(asciiCode, 2);;
bits = result.PadLeft(8, '0').ToCharArray();
return string.Join("",bits);
}
It might be a bit complicated but it is working. However my main problem is that I want to invert the process: ie from a sequence such as 0011000100110010 I should retrieve the int which is 12. Can someone help me to get on the right track?
Any help is greatly appriciated
Given the fact that you are learning C#, I will give you a simple, straightforward example even if it is not optimal or fancy. I think it would serve you purpose better.
static int GetInt(string value)
{
double result = 0d;//double
IEnumerable<char> target = value.Reverse();
int index = 0;
foreach (int c in target)
{
if (c != '0')
result += (c - '0') * Math.Pow(2, index);
index++;
}
return (int)result;
}
This code will work with any padding. Also, you can change it to Int16 if you will or extend it as you want. Also, it assumes that the given string has the least significant bit at the end (little endian).
var int16 = Convert.ToInt16("0011000100110010", 2);
Related
I have a large float that I want to convert into a string with commas without rounding.
Here is what I have:
String.Format("{0:#,###}", val);
This turns 17154177 into 17,154,180
I would like to keep the commas but not round at the end using c#.
This may be what you're looking for
using System;
class MainClass {
public static void Main (string[] args) {
float original = 17154177;
// 1. Convert the number to a string
string value = original.ToString("R");
// 2. Reverse the string
string reversed = Reverse(value);
// 3. Add the comma on each third number, backwards
string formatted = "";
for(int i = 0; i < reversed.Length; i++) {
if ((i+1) % 3 == 0) {
formatted += reversed[i] + ",";
} else {
formatted += reversed[i];
}
}
// 4. Reverse it back to the original order
formatted = Reverse(formatted);
Console.WriteLine (formatted);
}
/* Reverses a string */
public static string Reverse(string text)
{
char[] cArray = text.ToCharArray();
string reverse = String.Empty;
for (int i = cArray.Length - 1; i > -1; i--)
{
reverse += cArray[i];
}
return reverse;
}
}
I got the reverse method from this question.
Change your data type to decimal (28-29 significant digits) to have higher precision compared to float (7 digits).
Or you can change it to var. It will let the compiler figure out the best data type to use.
var number = 17154177;
Console.WriteLine(String.Format("{0:#,###}", number));
See this fiddler link, working code
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 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.
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);
I am doing a security presentation for my Computer and Information Security course in a few weeks time, and in this presentation I will be demonstrating the pros and cons of different attacks (dictionary, rainbow and bruteforce). I am do the dictionary and rainbow attacks fine but I need to generate the bruteforce attack on the fly. I need to find an algorithm that will let me cycle though every combination of letter, symbol and number up to a certain character length.
So as an example, for a character length of 12, the first and last few generations will be:
a
ab
abc
abcd
...
...
zzzzzzzzzzzx
zzzzzzzzzzzy
zzzzzzzzzzzz
But it will also use numbers and symbols, so it's quite hard for me to explain... but I think you get the idea. Using only symbols from the ASCII table is fine.
I can kind of picture using an ASCII function to do this with a counter, but I just can't work it out in my head. If anyone could provide some source code (I'll probably be using C#) or even some pseudo code that I can program a function from that'd be great.
Thank you in advance. :)
A recursive function will let you run through all combinations of ValidChars:
int maxlength = 12;
string ValidChars;
private void Dive(string prefix, int level)
{
level += 1;
foreach (char c in ValidChars)
{
Console.WriteLine(prefix + c);
if (level < maxlength)
{
Dive(prefix + c, level);
}
}
}
Assign the set of valid characters to ValidChars, the maximum length of string you want to maxlength, then call Dive("", 0); and away you go.
You need to generate all combinations of characters from a set of valid characters ; let's call this set validChars. Basically, each set of combinations of length N is a cartesian product of validChars with itself, N times. That's pretty easy to do using Linq:
char[] validChars = ...;
var combinationsOfLength1 =
from c1 in validChars
select new[] { c1 };
var combinationsOfLength2 =
from c1 in validChars
from c2 in validChars
select new[] { c1, c2 };
...
var combinationsOfLength12 =
from c1 in validChars
from c2 in validChars
...
from c12 in validChars
select new[] { c1, c2 ... c12 };
var allCombinations =
combinationsOfLength1
.Concat(combinationsOfLength2)
...
.Concat(combinationsOfLength12);
Obviously, you don't want to manually write the code for each length, especially if you don't know in advance the maximum length...
Eric Lippert has an article about generating the cartesian product of an arbitrary number of sequences. Using the CartesianProduct extension method provided by the article, you can generate all combinations of length N as follows:
var combinationsOfLengthN = Enumerable.Repeat(validChars, N).CartesianProduct();
Since you want all combinations from length 1 to MAX, you can do something like that:
var allCombinations =
Enumerable
.Range(1, MAX)
.SelectMany(N => Enumerable.Repeat(validChars, N).CartesianProduct());
allCombinations is an IEnumerable<IEnumerable<char>>, if you want to get the results as a sequence of strings, you just need to add a projection:
var allCombinations =
Enumerable
.Range(1, MAX)
.SelectMany(N => Enumerable.Repeat(validChars, N).CartesianProduct())
.Select(combination => new string(combination.ToArray()));
Note that it's certainly not the most efficient solution, but at least it's short and readable...
You can try this code, that use recursion to print all possible strings of 0 to stringsLenght chars lenght, composed by all combination of chars from firstRangeChar to lastRangeChar.
class BruteWriter
{
static void Main(string[] args)
{
var bw = new BruteWriter();
bw.WriteBruteStrings("");
}
private void WriteBruteStrings(string prefix)
{
Console.WriteLine(prefix);
if (prefix.Length == stringsLenght)
return;
for (char c = firstRangeChar; c <= lastRangeChar; c++)
WriteBruteStrings(prefix + c);
}
char firstRangeChar='A';
char lastRangeChar='z';
int stringsLenght=10;
}
This look to be faster than the solution of #dthorpe.I've compared the algorthms using this code:
class BruteWriter
{
static void Main(string[] args)
{
var st = new Stopwatch();
var bw = new BruteWriter();
st.Start();
bw.WriteBruteStrings("");
Console.WriteLine("First method: " + st.ElapsedMilliseconds);
for (char c = bw.firstRangeChar; c <= bw.lastRangeChar; c++)
bw.ValidChars += c;
st.Start();
bw.Dive("", 0);
Console.WriteLine("Second method: " + st.ElapsedMilliseconds);
Console.ReadLine();
}
private void WriteBruteStrings(string prefix)
{
if (prefix.Length == stringsLenght)
return;
for (char c = firstRangeChar; c <= lastRangeChar; c++)
WriteBruteStrings(prefix + c);
}
char firstRangeChar='A';
char lastRangeChar='R';
int stringsLenght=5;
int maxlength = 5;
string ValidChars;
private void Dive(string prefix, int level)
{
level += 1;
foreach (char c in ValidChars)
{
if (level <= maxlength)
{
Dive(prefix + c, level);
}
}
}
}
and, on my pc, I get these results:
First method: 247
Second method: 910
public void BruteStrings(int maxlength)
{
for(var i=1;i<i<=maxlength;i++)
BruteStrings(Enumerable.Repeat((byte)0,i));
}
public void BruteStrings(byte[] bytes)
{
Console.WriteLine(bytes
.Cast<char>()
.Aggregate(new StringBuilder(),
(sb,c) => sb.Append(c))
.ToString());
if(bytes.All(b=>b.MaxValue)) return;
bytes.Increment();
BruteStrings(bytes);
}
public static void Increment(this byte[] bytes)
{
bytes.Last() += 1;
if(bytes.Last == byte.MinValue)
{
var lastByte = bytes.Last()
bytes = bytes.Take(bytes.Count() - 1).ToArray().Increment();
bytes = bytes.Concat(new[]{lastByte});
}
}
Another alternative i did, that return a string.
I did not care about the performance of the thing since it was not for a real world scenario.
private void BruteForcePass(int maxLength)
{
var tempPass = "";
while (tempPass.Length <= maxLength)
{
tempPass = GetNextString(tempPass);//Use char from 32 to 256
//Do what you want
}
}
private string GetNextString(string initialString, int minChar= 32, int maxChar = 256)
{
char nextChar;
if (initialString.Length == 0)
{
nextChar = (char)minChar;//the initialString Length will increase
}
else if (initialString.Last() == (char)maxChar)
{
nextChar = (char)minChar;
var tempString = initialString.Substring(0, initialString.Length -1);//we need to increment the char just before the last one
initialString = GetNextString(tempString, minChar, maxChar);
}
else
{
nextChar = (char)(initialString.Last() + 1);//Get the lash Char and increment it;
initialString= initialString.Remove(initialString.Length - 1);//Remove the last char.
}
return initialString + nextChar;
}