I am trying to get some data to write to a binary file. The data consists of multiple values (strings, decimal, ints) that need to be a single string and then written to a binary file.
What I have so far creates the file, but it's putting my string in there as they appear and not converting them to binary, which I assume should look like 1010001010 etc. when I open the file in notepad?
The actual output is Jesse23023130123456789.54321 instead of the binary digits.
Where have I steered myself wrong on this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace BinaryData
{
class Program
{
static void Main(string[] args)
{
string name = "Jesse";
int courseNum = 230;
int num = 23130;
decimal d = 123456789.54321M;
string combined = name + courseNum + num + d;
FileStream writeStream;
writeStream = new FileStream("BinaryData.dat", FileMode.Create);
BinaryWriter bw = new BinaryWriter(writeStream);
bw.Write(combined);
}
}
}
There's more than one way to do this, but here's a basic approach. After you combine everything into a single string iterate through the string and convert each character into it's binary representation with Convert.ToString(char, 2). ASCII characters normally will be 7 bits or less in length, so you'll need to PadLeft(8, '0') to ensure 8 bits per byte. Then for the reverse you just grab 8 bits at a time and convert it back to its ASCII character. Without padding with leading 0's to ensure eight bits you won't be sure how many bits make up each character in the file.
using System;
using System.Text;
public class Program
{
public static void Main()
{
string name = "Jesse";
int courseNum = 230;
int num = 23130;
decimal d = 123456789.54321M;
string combined = name + courseNum + num + d;
// Translate ASCII to binary
StringBuilder sb = new StringBuilder();
foreach (char c in combined)
{
sb.Append(Convert.ToString(c, 2).PadLeft(8, '0'));
}
string binary = sb.ToString();
Console.WriteLine(binary);
// Translate binary to ASCII
StringBuilder decodedBinary = new StringBuilder();
for (int i = 0; i < binary.Length; i += 8)
{
decodedBinary.Append(Convert.ToChar(Convert.ToByte(binary.Substring(i, 8), 2)));
}
Console.WriteLine(decodedBinary);
}
}
Results:
01001010011001010111001101110011011001010011001000110011001100000011001000110011001100010011001100110000001100010011001000110011001101000011010100110110001101110011100000111001001011100011010100110100001100110011001000110001
Jesse23023130123456789.54321
Fiddle Demo
Here you go:
The main method:
static void Main(string[] args)
{
string name = "Jesse";
int courseNum = 230;
int num = 23130;
decimal d = 123456789.54321M;
string combined = name + courseNum + num + d;
string bitString = GetBits(combined);
System.IO.File.WriteAllText(#"your_full_path_with_exiting_text_file", bitString);
Console.ReadLine();
}
The method returns the bits, 0 and 1 based on your string input of-course:
public static string GetBits(string input)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in Encoding.Unicode.GetBytes(input))
{
sb.Append(Convert.ToString(b, 2));
}
return sb.ToString();
}
If you want to create the .txt file then add the code for it. This example has already a .txt created, so it just needs the full path to write to it.
Related
I have a string which comprise lots of letters. I have used the following code to convert it to numbers, but the new string t still gives me imperfect result.
For example:
tung2003 -> -1-1-1-12003
What I expected: 1161171101032003 (116 is the ASCII code of t, 117 is the ASCII code of u
string t=null;
foreach (char c in Properties.Settings.Default.password)
{
int ascii = (int)Char.GetNumericValue(c);
int counter=0;
counter = ascii;
t = t + Convert.ToString(counter);
}
The problem is the - character. I want my new string only comprises numbers.
It looks like you do not want the ASCII values of the numbers based on your expected output. In that case you can just do something like this:
string input = "tung2003";
string output = string.Empty;
foreach(char c in input)
{
if(char.IsNumber(c))
{
output += c;
}
else
{
output += ((byte)c).ToString();
}
}
//output is now: 1161171101032003
Fiddle here
Also added as a Linq expression for a short hand solution.
// Method 1 Linq
string output = string.Concat(("tung2003".ToCharArray()
.Select(s=> char.IsDigit(s) ? s.ToString() : ((int)s).ToString())));
// Method 2
string input = "tung2003";
string output = string.Empty;
foreach (char c in input)
{
if (Char.IsDigit(c)) output += c.ToString();
else output += ((int)c).ToString();
}
Extrapolating your output it looks like you want two different things. You want to tally each ascii character as long as it is a letter and extract the numeric values to append. The following provides three options, the first is to tally the ascii values from letters and the other two are ways to extract only digits. Because your code example uses a Password I am assuming you are trying to do some sort of custom hashing and if that is the case you should use a Hash implementation from the Cryptography namespace or some other package.
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
var combined = OnlyLettersToAscii("tung2003") + OnlyNumbers("tung2003");
Console.WriteLine($"Input: tung2003 Output: {OnlyNumbers("tung2003")}");
Console.WriteLine($"Input: tung2003 Output Regex: {OnlyNumbersWithRegex("tung2003")}");
Console.ReadKey();
}
private static string OnlyLettersToAscii(string originalString)
{
if (string.IsNullOrWhiteSpace(originalString)) return originalString;
return string.Join(string.Empty, originalString.ToArray()
.Where(w => char.IsLetter(w))
.Select(s => ((int)s).ToString()));
}
private static string OnlyNumbers(string originalString)
{
if (string.IsNullOrWhiteSpace(originalString)) return originalString;
return new string(originalString.Where(w => char.IsDigit(w)).ToArray());
}
public static string OnlyNumbersWithRegex(string originalString)
{
return Regex.Replace(originalString, #"[^\d]", string.Empty);
}
}
}
string t = "";
foreach (char c in Properties.Settings.Default.password)
{
if (IsNumber(x)) t += System.Convert.ToInt32(c).ToString();
else
{
t += c.ToString();
}
}
Moreover, if you just want to get rid off '-' the use this code: t =String.Replace(t, '-');
I am after some help in creating a byte array that will allow the following:
bytes 1-2 : An integer, n, that specifies the length of the file name
3 - n+2 : The name of the file
n+3 - n+10 : The last modified date of the file
n+11 - n+12 : Integer with value 1
n+13 - n+16 : long integer with the length of the file data
n+17 - n+20 : long integer with value 0
n+21 - end : The file's content.
I already have the following code which places the file into the byte array, but this is on the the last portion.
byte[] filebytes;
st.birth_certificate = detail[4];
downloadfile.HTML = detail[4];
downloadfile.fileName = downloadfile.GetFileNameFromUrl(st.birth_certificate);
downloadfile.toLocation = #"c:\temp\" + downloadfile.fileName;
if (downloadfile.DownloadFile())
{
filebytes= File.ReadAllBytes(downloadfile.toLocation);
st.birth_certificate_file = filebytes;
}
Any help would be greatly appreciated.
Better to do with BinaryReader. I'm not sure if numbers are hex values or ascii numbers (or Big/Little Endian) so I'm doing a little guessing. Code may need some minor tweaks :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string URL = "enter you url here";
FileStream sReader = File.OpenRead(URL);
BinaryReader reader = new BinaryReader(sReader);
int filenameLength = reader.ReadInt16();
string filename = Encoding.UTF8.GetString(reader.ReadBytes(filenameLength));
int year = int.Parse(Encoding.UTF8.GetString(reader.ReadBytes(4)));
int month = int.Parse(Encoding.UTF8.GetString(reader.ReadBytes(2)));
int day = int.Parse(Encoding.UTF8.GetString(reader.ReadBytes(2)));
DateTime date = new DateTime(year, month, day);
short number1 = reader.ReadInt16();
int number2 = reader.ReadInt32();
byte[] data = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position + 1));
}
}
}
I have a hard time figuring out how to remove extra letters using Regex.
I have this example below that says that it has 42 of "|" (vertical bars) per line.
|V.7|42|
1|0|1|58|4|4|351|25|8|||1|0||6|3|1000|49|20|430|17|6|0|10|0|1200|25||30|20|20|20|20|0|100|61028|1|0|0|1|1|0|
1|0|1|58|4|4|351|25|8|||1|0||6|3|1000|49|20|430|17|6|0|10|0|1200|25||30|20|20|20|20|0|100|61028|1|0|0|1|1|0|
2|543|2|58|4|4|366|26|9|100||2|200||8|3|1000|49|20|430|17|6|10|21|54|2400|36||30|20|20|20|20|543|150|61028|2|100|1|2|2|0|
3|1230|3|60|5|5|390|26|10|100||3|1500||10|3|1000|49|20|430|17|6|10|32|123|4800|46||30|20|20|20|20|1230|200|61028|3|1000|2|3|3|0|
4|2002|4|61|6|6|424|27|12|100||4|6000||12|4|769|37|15|315|12|4|10|45|200|9600|57||30|20|20|20|20|2002|250|61028|4|5000|3|4|4|0|
5|3306|5|63|7|7|468|29|14|100||5|18000||16|4|556|27|11|208|8|2|10|58|331||69||30|20|20|20|20|3306|300|61027|1|10000|4|5|5|0|
6|4950|6|66|8|8|522|31|17|100||6|||18|4|435|21|9|147|6|1|10|74|495||80||30|20|20|20|20|4950|350|61027|2|30000|5|6|6|0|
7|6947|7|69|10|10|585|33|20|100||7|||20|4|333|17|7|97|4|1|10|90|695||92||20|15|15|15|15|6947|400|61027|3|50000|6|7|7|0|
8|9309|8|73|12|12|658|35|24|100||8|||24|4|286|14|6|73|3|1|10|109|931||105||20|15|15|15|15|9309|450|61026|1|100000|7|8|8|0|
9|12050|9|77|14|14|741|38|28|100||9|||27|5|250|13|5|55|3|1|10|129|1205||117||20|15|15|15|15|12050|500|61026|2|300000|8|9|9|0|
10|15183|10|82|16|16|834|41|33|100|100|10|||29|5|222|11|4|0|0|0|10|151|1366||130|5|20|15|15|15|15|15183|550|61025|1|500000|9|10|10|0|
11|18720|11|87|19|19|936|45|38|100|100|11|||31|5|200|10|4|0|0|0|11|176|1685||143|10|20|15|15|15|15|18720|600|||||||0|
12|21335|12|92|22|22|1048|48|44|100|100|12|||36|5|182|9|4|0|0|0|12|203|2134||157|15|10|15|10|10|10|21335|650|||||||0|
Now I have another one with 45, what I want is to remove the new letters so that it has exactly 42 vertical bars like above.
|V.8|45|
1|0|1|58|4|4|351|25|8|||1|0||6|3|1000|49|20|430|17|6|0|10|0|1200|25||30|20|20|20|20|0|100|61028|1|0|0|1|1|0|5000|40022|1|
2|543|2|58|4|4|366|26|9|100||2|200||8|3|1000|49|20|430|17|6|10|21|54|2400|36||30|20|20|20|20|543|150|61028|2|100|1|2|2|0|25000|61034|1|
3|1230|3|60|5|5|390|26|10|100||3|1500||10|3|1000|49|20|430|17|6|10|32|123|4800|46||30|20|20|20|20|1230|200|61028|3|1000|2|3|3|0|75000|40250|1|
4|2002|4|61|6|6|424|27|12|100||4|6000||12|4|769|37|15|315|12|4|10|45|200|9600|57||30|20|20|20|20|2002|250|61028|4|5000|3|4|4|0|160000|61035|1|
5|3306|5|63|7|7|468|29|14|100||5|18000||16|4|556|27|11|208|8|2|10|58|331||69||30|20|20|20|20|3306|300|61027|1|10000|4|5|5|0|300000|40355|3|
6|4950|6|66|8|8|522|31|17|100||6|||18|4|435|21|9|147|6|1|10|74|495||80||30|20|20|20|20|4950|350|61027|2|30000|5|6|6|0||||
7|6947|7|69|10|10|585|33|20|100||7|||20|4|333|17|7|97|4|1|10|90|695||92||20|15|15|15|15|6947|400|61027|3|50000|6|7|7|0||||
8|9309|8|73|12|12|658|35|24|100||8|||24|4|286|14|6|73|3|1|10|109|931||105||20|15|15|15|15|9309|450|61026|1|100000|7|8|8|0||||
9|12050|9|77|14|14|741|38|28|100||9|||27|5|250|13|5|55|3|1|10|129|1205||117||20|15|15|15|15|12050|500|61026|2|300000|8|9|9|0||||
10|15183|10|82|16|16|834|41|33|100|100|10|||29|5|222|11|4|0|0|0|10|151|1366||130|5|20|15|15|15|15|15183|550|61025|1|500000|9|10|10|0||||
11|18720|11|87|19|19|936|45|38|100|100|11|||31|5|200|10|4|0|0|0|11|176|1685||143|10|20|15|15|15|15|18720|600|||||||0||||
12|21335|12|92|22|22|1048|48|44|100|100|12|||36|5|182|9|4|0|0|0|12|203|2134||157|15|10|15|10|10|10|21335|650|||||||0||||
And I have this code at the moment:
public string Fix(string FileName, int columnsCount)
{
var InputFile = File.ReadLines(FileName).Skip(1).ToArray();
string Result = "";
for(int i = 0; i < InputFile.Length; i++)
{
int FoundMatches = Regex.Matches(Regex.Escape(InputFile[i]), FindWhatTxtBox.Text).Count;
// If too many letters found, trim the rest.
if(FoundMatches > CountTxtBox.Text.Length)
{
string CurrentLine = InputFile[i];
}
}
return Result;
}
As you can see each line has either one to no numbers inside its vertical bar. How can I remove the extra letters?
Do you have to use a RegEx? It can also be done with string manipulation like this:
using System;
using System.Linq;
public class Program
{
public static void Main()
{
string s = "1|0|1|58|4|4|351|25|8|||1|0||6|3|1000|49|20|430|17|6|0|10|0|1200|25||30|20|20|20|20|0|100|61028|1|0|0|1|1|0|5000|40022|1|";
var arr = s.Split('|') ;
var retVal = String.Join("|", arr.Take(43));
Console.WriteLine(retVal);
}
}
It takes 43 because the 1st digit seems a counter to me... But you can make it 42 of course. Beware that this code will fail is there are less than 43 entries to work with.
Too simple to use Regex. See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.txt";
const string OUTPUT_FILENAME = #"c:\temp\test1.txt";
static void Main(string[] args)
{
StreamReader reader = new StreamReader(INPUT_FILENAME);
StreamWriter writer = new StreamWriter(OUTPUT_FILENAME);
string inputLine = "";
int lineCount = 0;
while ((inputLine = reader.ReadLine()) != null)
{
if (++lineCount == 1)
{
writer.WriteLine(inputLine);
}
else
{
string[] inputArray = inputLine.Split(new char[] {'|'});
writer.WriteLine(string.Join("|", inputArray.Take(43)));
}
}
reader.Close();
writer.Flush();
writer.Close();
}
}
}
Here is a data file, let us keep it easy by only needing 5 items but still using Regex.
Keep your examples small for StackOverflow...one will get more answers.
The below code can be changed to 42 ({0,42}) or any number as needed, but the example will read then write out only 5.
Data File
1|2|3|4|5|6|7|8|9|10
10|9|8|7|6|5|4|3|2|1|0|1|
||||||||||||11|12|
Code To get 0 to 5 Items per line
var data = File.ReadAllText(#"C:\Temp\test.txt");
string pattern = #"^(\d*\|){0,5}";
File.WriteAllLines(#"C:\Temp\testOut.txt",
Regex.Matches(data, pattern, RegexOptions.Multiline)
.OfType<Match>()
.Select(mt => mt.Groups[0].Value));
Resultant File
1|2|3|4|5|
10|9|8|7|6|
|||||
I've been creating a code breaking software and I need to convert the characters from a text file into ascii numbers to allow the shift. I have left my code below but could someone explain how I could do this?
using System;
using System.IO;
namespace CipherDecoder
{
class Program
{
static void Main(string[] args)
{
string fileText = #"C:/Users/Samuel/Documents/Computer_Science/PaDS/caeserShiftEncodedText";
string cipherText = File.ReadAllText(fileText);
string output = #"C:\\Users\Samuel\Documents\Computer_Science\PaDS\output.txt\";
char[] cipherChars = new char[691];
int j = 0;
foreach (char s in cipherText)
{
cipherChars[j] = s;
j++;
}
for(int i = 0; i < cipherChars.Length; i++)
{
cipherChars[i] = cipherChars[i];
}
}
}
}
To get the int values into an int array you could just do this with as a LINQ select. For example:
string fileText = #"C:/Users/Samuel/Documents/Computer_Science/PaDS/caeserShiftEncodedText";
int [] charactersAsInts = File.ReadAllText(fileText).Select(chr => (int)chr).ToArray();
You can,
var asciiNumbersArray = cipherText.Cast<int>().ToArray();
If you cast a char to int you get the ascii number in decimal system.
I'm a newer programmer with C#. I am having an issue where my character frequency reading program is not displaying the ASCII values correctly. What it is supposed to do is read from a text file, convert all uppercase to lowercase, display the ASCII values, frequency appeared, and percentage of the total number of characters each character appears in the file and then sort the list by frequency. Below is my code so far:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.IO;
using LibUtil;
using LibDate;
namespace Ch8Prb3
{
class Program
{
const string INPUT_FILE_NAME = "\\CIS210\\Ch8Prb3\\TextDat.Txt";
const string OUTPUT_FILE_NAME = "\\CIS210\\Ch8Prb3\\Ch8Prb3Rpt.Txt";
int count;
static StreamReader fileIn;
static StreamWriter fileOut;
static void Main()
{
ConsoleApp.ClrScr(); IdentifyApplication();
OpenFiles(); LetterFreq();
CloseFiles();
}
static void IdentifyApplication()
{
Console.WriteLine();
Console.WriteLine("Application: Ch8Prb3 -- Find and display a character-frequency ");
Console.WriteLine(" report of only letter chracters and their");
Console.WriteLine(" ASCII values from a text file.");
Console.WriteLine();
}
static void OpenFiles()
{
try
{
fileIn = File.OpenText(INPUT_FILE_NAME);
Console.WriteLine("{0} was opened", INPUT_FILE_NAME);
}
catch
{
Console.WriteLine("Error: {0} does not exist\n", INPUT_FILE_NAME);
ConsoleApp.Exit();
}
try
{
fileOut = File.CreateText(OUTPUT_FILE_NAME);
Console.WriteLine("{0} was created\n", OUTPUT_FILE_NAME);
}
catch
{
Console.WriteLine("Error: {0} could not be created\n", OUTPUT_FILE_NAME);
ConsoleApp.Exit();
}
}
static void LetterFreq()
{
int[] c = new int[(int)char.MaxValue];
int total = 0;
int j = 0;
string s = File.ReadAllText("\\CIS210\\Ch8Prb3\\TextDat.Txt");
string l = Convert.ToString(Encoding.ASCII.GetBytes(s));
s = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToLower(s.ToLower());
double percent;
foreach (char t in s)
{
c[(int)t]++;
}
PrintHeader();
for (int i = 0; i < (int)char.MaxValue; i++)
{
if (c[i] > 0 && char.IsLetter((char)i))
{
total += c[i];
percent = c[i] / total * 100;
fileOut.WriteLine(" {0} {1,3} {2,3} {3,2:f2}", (char)i, l, c[i], percent);
}
}
fileOut.WriteLine();
fileOut.WriteLine("Number of Characters: {0}", total);
}
static void PrintHeader()
{
fileOut.WriteLine(" Chapter 8 Problem 3");
fileOut.WriteLine("Character Frequency Report");
fileOut.WriteLine(" {0:MM/dd/yyyy}", Date.Today);
fileOut.WriteLine();
fileOut.WriteLine(" ASCII ");
fileOut.WriteLine("Char Value Freq Percent");
fileOut.WriteLine("---- ----- ---- -------");
}
static void CloseFiles()
{
fileIn.Close(); fileOut.Close();
}
}
}
Instead of getting the ASCII value of each character, I'm getting System.Byte [] all the way down the ASCII column.
Help!
This is the problem:
Convert.ToString(Encoding.ASCII.GetBytes(s));
Encoding.GetBytes(string) returns a byte[], and calling Convert.ToString() on that will just return System.Byte[].
It's not clear why you're using Encoding.ASCII at all here - you've got the contents of the file as a string, on the previous line:
string s = File.ReadAllText("\\CIS210\\Ch8Prb3\\TextDat.Txt");
Just use that instead of l. It's not clear what you're expecting to do with l anyway, to be honest. By "ASCII value" if you mean the Unicode code point for the character, just cast i to int:
fileOut.WriteLine(" {0} {1,3} {2,3} {3,2:f2}", (char)i, (int) i, c[i], percent);
Oh, and you probably want to change the way you're computing percent, too - you're using integer arithmetic, so the result will always be 0.
It's not clear why you're lower-casing the string twice either, by the way. Don't you think once is enough? Why are you lower-casing at all?
Oh, and you open an input file, but never do anything with it. Why?
There are various other things I'd change about your code - not least the layout (one statement per line, almost always!) - but this'll do for a start.
You program con be condensed considerably using list and groupby:
class Program
{
const string INPUT_FILE_NAME = "\\CIS210\\Ch8Prb3\\TextDat.Txt";
static void Main(string[] args)
{
var s = System.IO.File.ReadAllText(INPUT_FILE_NAME).ToLower();
var list = s.ToList();
var group = list.GroupBy(i => i);
foreach (var g in group)
{
Console.WriteLine("{0} {1}", g.Key, g.Count());
}
Console.ReadLine();
}
}