Creating a binary file from an IntelHex in C# - c#

I'm trying to create a binary file from a intelHex file. Iside the intelHex file I have data and address to which I should write the data inside the binary file.
IntelHex file looks like that
:10010000214601360121470136007EFE09D2190140
:100110002146017EB7C20001FF5F16002148011988
:10012000194E79234623965778239EDA3F01B2CAA7
:100130003F0156702B5E712B722B732146013421C7
:00000001FF
So I have 4 lines here with data since the last one tells us thats the end of file.
Here is what I'm doing to create the file
while (!streamReader.EndOfStream)
{
string temp = String.Empty;
int address = 0;
line = streamReader.ReadLine();
// Get address for each data
address = Convert.ToInt32(line.Substring(3, 4), 16);
// Get data from each line
temp = line.Substring(7, 2);
if (temp == "01")
break;
else
{
temp = line.Substring(9, line.Length - 11);
string[] array = new string[(temp.Length / 2)];
int j = 0;
for (int i = 0; i < array.Length; ++i)
{
array[i] = temp[j].ToString() + temp[j + 1].ToString();
j = j + 2;
}
temp = String.Empty;
for (int i = 0; i < array.Length; ++i)
{
temp = temp + Convert.ToChar(Convert.ToInt32(array[i], 16));
}
}
binaryWriter.Seek(address, SeekOrigin.Begin);
binaryWriter.Write(temp);
binaryWriter.Flush();
}
Console.WriteLine("Done...\nPress any key to exit...");
The problem here is, that data in binary file in some places is not equal to data from the intelHex file. Looks like there is some random data added to the file and I do not know from where. First time I saw that there is an additional data before the data from the intelHex file. For instance first data line starts with 21, but in binary file I have a number 12 before the 21. I do not know what is wrong here. Hope someone can help me or guide me where I can find some usefull informations about creating binary files in C#

<Generic answer pointing out that a Unicode character (char) is not an octet (byte), and that the code produces the wrong output because binary data is written as Unicode string to the file.>
Hint: use a byte[] for binary data, not a string.
Also: In before answers suggesting to use a StringBuilder for the loop.

Related

C# doesn't recognize some symbols

I read strings from text file, and among the strings there is one: "15121 ♥☺020 000000/=n531☻".
I use .Contain() method to spot ♥☺☻ symbols in the string, but it doesn't recognize them. For ♥,☺,☻ I also tried \u2665, \u263a, \u263b (as arguments for .Contain()), but none of them were recognized.
Moreover, I copied the string (from console output window) and pasted it into my code to compare symbols one by one.
string s = "15121 ♥☺020 000000/=n531☻"; // the same with "15121 \u2665\u263a020 000000/=n531\u263b"
for (int j = 0; j < s.Length; j++)
{
Console.WriteLine($"{line[j]} == {s[j]}: {line[j].Equals(s[j])}");
}
This is what I got:
What may be wrong and how do I recognize those symbols?
UPDATE: The input file I read strings from is a usual text file, and the strings inside looks like these (txt opened in Notepad):
As you can see, there is THE string among the others.
I don't use any encoding when reading the txt, and to specify how I do read the file and what the line is, here is my code:
string[] lines = File.ReadAllLines(path + target_file_name);
var list = new List<string>(lines);
for (int i = 0; i < list.Count; i++)
{
string line = list[i];
if (line.Length > 21)
{
Console.WriteLine(line);
if (line.Contains("/=n")) //used just to catch THE string
{
var line_b = Encoding.Unicode.GetBytes(line);
Console.WriteLine($"{line_b} : line = {line}");
foreach (byte m in line_b)
{
Console.Write(m + " ");
}
string s = "AAXX 15121 ♥☺020 000000/=n531☻";
Console.WriteLine();
var s_b = Encoding.Unicode.GetBytes(s);
Console.WriteLine($"{s_b} : s = {s}");
foreach (byte n in s_b)
{
Console.Write(n + " ");
}
Console.WriteLine();
for (int j = 0; j < s.Length; j++)
{
Console.WriteLine($"{line[j]} == {s[j]}: {line[j].Equals(s[j])}");
}
}
Reading all the lines from txt and converting them to List is a must for me. Thus, the line is a string line from initial txt file.
I have dumped the bytes of the inout text string var b = Encoding.Unicode.GetBytes(line); and compare with my literal (#pm100), and here is the result. Not quite sure what it does give me:
I'm sorry, I'm not willing to publish my code, and I may not understand some of your suggestions for I'm not very proficient in C# (and coding in general). So I would appreciate any further help as it is, if possible.

Merge 2 text files ASP.NET

I want to merge 2 .txt files into one text file. Let's say I have 2 text files. First one contains 100 rows only "Try Again". Like this one in the picture:
And the second text file contains bunch of random codes:
I want to merge these 2 text files, like this one in the picture below:
I have one week and I have not figured it out yet.
Just open both files and, in a loop, read four lines from the first and one line from the second. Output each line as it's read.
using (var outputFile = File.CreateText("OutputFile.txt"))
{
using (var input1 = File.OpenText("TryAgain.txt"))
using (var input2 = File.OpenText("File2.txt"))
{
while (!input1.EndOfStream && !input2.EndOfStream))
{
int i;
for (i = 0; i < 4 && !input1.EndOfStream; ++i))
{
var s1 = input1.ReadLine();
outputFile.WriteLine(s1);
}
if (i != 4) break; // end of first file
// now read one line from the other file, and output it
var s2 = input2.ReadLine();
outputFile.WriteLine(s2);
}
}
}
This has the advantage of not having to read both files into memory all at once, and you don't have to build the entire output in memory. Each line is output immediately after it's written.
Edit: I edit the code via Jim, he warned me and now it's working.
First you need to read both files and store all lines to string array. Then loop them like down bellow. Every fifth item you need to check and write from second file.
PS: I did not try the code but prob it will work without an error.
string[] first = System.IO.File.ReadAllLines("path of first txt file");
string[] second = System.IO.File.ReadAllLines("path of second txt file");
var sb = new StringBuilder();
var k = 0;
var m = 0;
for (int i = m; i < second.Length; i++)
{
m = i + 1;
for (int j = k; j < first.Length; j++)
{
k = j + 1;
if (j != 0 && j % 4 == 0)
{
sb.Append(second[i] + "\n");
break;
}
else
{
sb.Append(first[j] + "\n");
continue;
}
}
}
// create new txt file
var file = new System.IO.StreamWriter("path of third txt file");
file.WriteLine(sb.ToString());

Read part of a file as text and part as binary

I have a file done like this
10 NDI 27 2477 6358 4197 -67 0 VVFAˆ ÿÿÿÿ
The last column is binary.
I have to read this file, the problem is that I can not read it as a text because in some lines the last columns has a new line character and thus I wouldn't read the entire line.
Then I should read it as a binary file, but then how can I retrieve the first and the third column?
I tried by reading bytes in this way:
byte[] lines1 = System.IO.File.ReadAllBytes("D:\\dynamic\\ap1_dynamic\\AP_1.txt");
And then convert it into string with
for (i = 0; i < lines1.Length; i++) {
Convert.ToString(lines1[i],2);
}
but then it reads everything as 0 and 1.. I would like to read the first 8 columns as text, while the last one as binary..
I am using Visual Studio 2013, C#.
Reading the file as binary is correct, as you can convert part of the binary data to text. In this context binary means bytes.
Converting the bytes to binary is not what you want to do. In this context binary means text representation in base 2, but you don't want a text representation of the data.
If the lines are fixed length, you can do something like this to read the values:
int lineLen = 70; // correct this with the actual length
int firstPos = 0;
int firstLen = 3; // correct with actual length
int thirdPos = 15; // correct with actual position
int thirdLen = 3; // correct with actual length
int lastPos = 60; // correct with actual position
int lastLen = 10; // correct with actual length
int lines = lines.length / lineLength;
for (int i = 0; i < lines; i++) {
int first = Int32.Parse(Encoding.UTF8.GetString(i * lineLen + firstPos, firstLen).Trim());
int third = Int32.Parse(Encoding.UTF8.GetString(i * lineLen + thirdPos, thirdLen).Trim());
byte[] last = new byte[lastLen];
Array.Copy(lines1, i * lineLen + lastPos, last, 0, lastLen);
// do something with the data in first, third and last
}

Read hex in C# using IO

I'm new to C# moving from Java. I'm trying to read in a file using IO in HEX. When I read the first byte in I don't get what I'm seeing in my Hex editor.
I'm using
StreamReader reader = new StreamReader(fileDirectory);
int hexIn;
String hex;
for (int i = 0; (hexIn = reader.Read()) != -1; i++){
hex = Convert.ToString(hexIn, 16);
}
In Java I used
FileInputStream fis = new FileInputStream(file);
long length = file.length();
int hexIn;
String hex = "";
for(int i = 0; (hexIn = fis.read()) != -1; i++){
String s = Integer.toHexString(hexIn);
if(s.length() < 2){
s = "0" + Integer.toHexString(hexIn);
}
I hope this makes sense. Any help would be most apperciated :)
Thanks.
Don't use a StreamReader—that's only for characters in a certain encoding (default UTF8). Use a FileStream class instead:
FileStream fs = new FileStream(fileDirectory, FileMode.Open);
int hexIn;
String hex;
for (int i = 0; (hexIn = fs.ReadByte()) != -1; i++){
hex = string.Format("{0:X2}", hexIn);
}
You need such C# code to achieve the same results as your Java code:
hex = hexIn.ToString("X").PadLeft(2, '0');
The Convert.ToString also works, but IMO using the native ToString of the integer is better practice.
Anyway you were missing the PadLeft part that indeed caused 15 to be 'f' instead of 0F.

Calculating info_hash from UrlEncoded query string

Basically, I'm building a small tracker for experimental purposes. I've gotten quite far, and am now working on the announce part.
What I really can't figure out is how I should decode the info_hash query string provided.
From the specification, it is a urlencoded 20-byte SHA1 hash, which made me write this code,
byte[] foo = Encoding.Default.GetBytes(HttpUtility.UrlDecode(infoHash));
string temp = "";
foreach (byte b in foo)
{
temp += b.ToString("X");
}
Which gives 'temp' the following value,
5D3F3F3F3F5E3F3F3F153FE4033683F55693468
The first and last few characters are correct. This is the raw info_hash,
%5d%96%b6%f6%84%5e%ea%da%c5%15%c4%0e%403h%b9Ui4h
And this is what both uTorrent and my own tracker gives me as info_hash when generating it from the torrent file,
5D96B6F6845EEADAC515C40E403368B955693468
What am I doing wrong?
UrlDecode returns a string, but a SHA1 hash doesn't make sense if interpreted as (ANSI) string.
You need to decode the input string directly to an byte array, without the roundtrip to a string.
var s = "%5d%96%b6%f6%84%5e%ea%da%c5%15%c4%0e%403h%b9Ui4h";
var ms = new MemoryStream();
for (var i = 0; i < s.Length; i++)
{
if (s[i] == '%')
{
ms.WriteByte(
byte.Parse(s.Substring(i + 1, 2), NumberStyles.AllowHexSpecifier));
i += 2;
}
else if (s[i] < 128)
{
ms.WriteByte((byte)s[i]);
}
}
byte[] infoHash = ms.ToArray();
string temp = BitConverter.ToString(infoHash);
// "5D-96-B6-F6-84-5E-EA-DA-C5-15-C4-0E-40-33-68-B9-55-69-34-68"
HttpUtility.UrlDecodeToBytes

Categories

Resources