If I have some text file like abc.txt the I want to the hex value of that .txt file
like we see when we open notepad+ can click on hex...something like this
74 68 65 72 77 69 73 65 20 69 73 20 69 74 63 68
therwise is itch
69 6e 27 20 66 6f 72 20 61 20 66 69 67 68 74 2e
in' for a fight.
Now i want these hex values of individual letters.
I know how to read text by using FileStream() and StreamReader().
But now want these hex values how can i get this?
BinaryReader reader = new BinaryReader(new FileStream("C:\\file.ext", FileMode.Open, FileAccess.Read, FileShare.None));
reader.BaseStream.Position = 0x0; // The offset you are reading the data from
byte[] data = reader.ReadBytes(0x10); // Read 16 bytes into an array
reader.Close();
So assuming the input is therwise is itch:
string data_as_str = Encoding.Default.GetString(data); // Output: therwise is itch
string data_as_hex = BitConverter.ToString(data); // Output: 74-68-65-72-77-69-73-65-20-69-73-20-69-74-63-68
Open using FileStream, then use Read to get arrays of byte. For each element in the array convert to a hex pair with byteVal.ToString("x2") (use X2 if you want uppercase hex).
Related
I use a NFC-Reader to read data. The data will be stores as byte[] bytes_credentials. Receiving data is working fine but now I want to encode the 16 byte Array to String. I use string str = Encoding.Default.GetString(new_data); for decoding the array. The string output is working fine if the byte Array is fully "booked up" (16 of 16 bytes used), for example: This is an test! -> 54 68 69 73 20 69 73 20 61 6e 20 74 65 73 74 21. The problem i am facing is, that if the NFC-Array is not fully "booked up", the Array look like this: This is! -> 54 68 69 73 20 69 73 21 00 00 00 00 00 00 00 00. The output in console looks like this: This is!????????.
How can I CHECK and REMOVE the empty bytes (00) from the Array. So that the Output looks like this: This is!.
Thank you for helping!!!
I have checked previous posts but no of them are working for me...
You can use LINQ to filter your array further:
using System.Text;
var bytes_credentials = new byte[]
{
0x54,
0x68,
0x69,
0x73,
0x20,
0x69,
0x73,
0x21,
0,
0,
0,
0,
0,
0,
0,
0
};
Console.WriteLine(Encoding.Default.GetString(
bytes_credentials.Where(b => b != 0).ToArray()
));
To learn more about LINQ, take a look here: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
I'm getting strange behavior from simple program, which I'm using to learn how to use the serial port. The form have just one serial port control and one TextBox. Because it's just a test program I have disabled the thread call check.
I forgot to mention,that I'm using micro-controller to send 1000 bytes of data (read EEPROM).
The strange thing is that, when I read the data and just append it directly to the text box in the DataReceived event, everything is fine, but when I first pass the values to int[] array,and then use a loop to convert them to strings in HEX format and append them to the TextBox, there are some zeros, between the values.
Some code with results.
Case 1: read data and directly append to TextBox
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (sp1.BytesToRead > 0)
{
textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
}
}
And the result is (well,part of it,as i said there are 1000 bytes to receive...)
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C..... and so on
Case 2: first store the values to int array,and than convert them to string, and append to TextBox
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int[] buffer = new int[1000];
int i = 0;
while (sp1.BytesToRead > 0)
{
//textBox1.AppendText(sp1.ReadByte().ToString("X")+ " ");
buffer[i] = sp1.ReadByte();
i++;
}
int j = 0;
while (j < 1000)
{
textBox1.AppendText(buffer[j].ToString("X"));
j++;
}
I get a lot of 0's at random places, and it reads 4-5 times more data, than the 1000 in the loop
0123456789ABCDEF101112131415161718191A1B1C1D1E1F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF0123456789ABCDEF101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
What might be the reason for this strange behavior?
Thanks in advance
sp1_DataReceived is typically not called only once. Typically your computer handles received data faster than received. This means at some point the loop
while (sp1.BytesToRead > 0)
is left before all 1000 bytes are received. Just a short time later sp1_DataReceived is already called again because more of the 1000 bytes are now available. Since your first implementation only appends the bytes it doesen't matter. But your second implementation differs because you are always appending 1000 characters to your text. This could lead to a result of a multiple of 1000 characters with zeros appended.
To fix your problem you need to combine the bytes of multiple events. One solution could be to use a list like
private List<byte> buffer = new List<byte>();
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (sp1.BytesToRead > 0)
{
buffer.Add(sp1.ReadByte());
}
//Print if all bytes are available
if (buffer.Count >= 1000)
{
//Join the bytes to a string using LINQ
textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
buffer.Clear();
}
}
or an array like
private byte[] buffer = new byte[1000];
private int bufferIndex = 0;
private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
while (sp1.BytesToRead > 0 && bufferIndex < 1000)
{
buffer[bufferIndex ] = sp1.ReadByte();
bufferIndex ++;
}
//Print if all bytes are available
if (bufferIndex >= 1000)
{
//Join the bytes to a string using LINQ
textBox1.Text = String.Join("", buffer.Select(b => b.ToString("X")));
bufferIndex = 0;
}
}
Note that this are only some ideas and example implementations. Since I do not know if you are also receiving other messages at the port it is not possible to give a perfect suitable solution to solve your problem.
I have written the following unit test to test date time formatting:
using System;
using Windows.Globalization.DateTimeFormatting;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
namespace MyTests
{
[TestClass]
public class DateTimeFormatterTests
{
[DataTestMethod]
[DataRow(2, 3, 2017, "en", "Thursday, March 2")]
[DataRow(2, 3, 2017, "de", "Donnerstag, 2. März")]
public void Long_date_without_year_should_match_expected(int day, int month, int year, string regionCode, string expected)
{
DateTimeFormatterformatter = new DateTimeFormatter("dayofweek month day", new[] { regionCode });
string actual = formatter.Format(new DateTime(year, month, day));
Assert.AreEqual(expected, actual);
}
}
}
I don't understand why the assertion fails with the following error:
{"Assert.AreEqual failed. Expected:<Thursday, March 2>. Actual:<Thursday, March 2>. "}
Is this because the strings have different encoding?
After converting both strings into byte arrays using UTF8 encoding the content of the byte arrays looks like this:
actual:
e2 80 8e 54 68 75 72 73 64 61 79 e2 80 8e 2c 20 e2 80 8e 4d 61 72 63 68 e2 80 8e 20 e2 80 8e 32
expected:
54 68 75 72 73 64 61 79 2c 20 4d 61 72 63 68 20 32
The octets e2 80 8e show that you have several U+200E characters in the actual string. U+200E is a control character for overriding the bi-directional text algorithm and insisting that what follows be written left-to-right, even if it's a case (such as Hebrew or Arabic characters) that would normally be written right-to-left.
The expected string does not have them.
Presumably that control character got copied into either your test data or into the actual source of the formatter you are testing. In the latter case, be glad the testing caught it. (Alternatively, maybe it's meant to be there for some reason).
assume i got the following byte[]
0C 00 21 08 01 00 00 00 86 1B 06 00 54 51 53 65 72 76 65 72
with bitconverter BitConverter.ToString i can convert it to
0C-00-21-08-01-00-00-00-86-1B-06-00-54-51-53-65-72-76-65-72
how do i convert it back from string to byte[] to get
0C 00 21 08 01 00 00 00 86 1B 06 00 54 51 53 65 72 76 65 72
ascii encoding and other methods always getting me the equivalent bytes to the string but what i really need is the string to be byte[] as it is, i know if i did a reversing operation (using getbytes then tostring) ill end up with the same string but what i care about is while at getbytes to get the exact bytes
as i said
to put
0C-00-21-08-01-00-00-00-86-1B-06-00-54-51-53-65-72-76-65-72
AS string
and get
0C 00 21 08 01 00 00 00 86 1B 06 00 54 51 53 65 72 76 65 72
As byte[]
thanks in advance
You need this
byte[] bytes = str.Split('-').Select(s => Convert.ToByte(s, 16)).ToArray();
You can use SoapHexBinary class in System.Runtime.Remoting.Metadata.W3cXsd2001 namespace
string s = "0C-00-21-08-01-00-00-00-86-1B-06-00-54-51-53-65-72-76-65-72";
byte[] buf = SoapHexBinary.Parse(s.Replace("-"," ")).Value;
Remenber that BitConverter.ToString returns an equivalent hexadecimal string representation,so
if you decide to stick with it converting back as follow:
string temp = BitConverter.ToString(buf);//buf is your array.
byte[] newbuf = temp.Split('-').Select(s => Convert.ToByte(s,16)).ToArray();
But the safest way to convert bytes to string and back is base64:
string str = Convert.ToBase64String(buf);
byte[] result = Convert.FromBase64String(str);
I want to send this hex packet:
00 38 60 dc 00 00 04 33 30 3c 00 00 00 20 63 62
39 62 33 61 36 37 34 64 31 36 66 32 31 39 30 64
30 34 30 63 30 39 32 66 34 66 38 38 32 62 00 06
35 2e 31 33 2e 31 00 00 02 3c
so i build the string:
string packet = "003860dc0000" + textbox1.text+ "00000020" + textbox2.text+ "0006" + textbox3.text;
then "convert" it to ascii:
conn_str = HexString2Ascii(packet);
then i send the packet... but i have this:
00 38 60 **c3 9c** 00 00 04 33 30 3c 00 00 00 20 63
62 39 62 33 61 36 37 34 64 31 36 66 32 31 39 30
64 30 34 30 63 30 39 32 66 34 66 38 38 32 62 00
06 35 2e 31 33 2e 31 00 00 02 3c **0a**
why??
Thank you!
P.S.
the function is:
private string HexString2Ascii(string hexString)
{
byte[] tmp;
int j = 0;
int lenght;
lenght=hexString.Length-2;
tmp = new byte[(hexString.Length)/2];
for (int i = 0; i <= lenght; i += 2)
{
tmp[j] =(byte)Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
j++;
}
return Encoding.GetEncoding(1252).GetString(tmp);
}
EDIT:
if i convert directly in byte, the hex packet in coded as string:
00000000 30 30 33 38 36 30 64 63 30 30 30 30 30 34 33 33 003860dc 00000433
00000010 33 30 33 43 30 30 30 30 30 30 32 30 33 34 33 32 303C0000 00203432
00000020 36 33 36 33 33 35 33 39 33 32 33 34 36 36 33 39 63633539 32346639
00000030 36 33 33 39 33 31 33 39 33 30 33 36 33 33 36 35 63393139 30363365
00000040 33 35 36 33 36 35 36 35 36 35 33 31 33 39 33 38 35636565 65313938
00000050 36 33 33 31 36 34 33 34 36 33 33 30 30 30 30 36 63316434 63300006
00000060 33 35 32 65 33 31 33 33 32 65 33 31 30 30 30 30 352e3133 2e310000
00000070 30 32 33 43 023C
You cannot convert raw binary data to string data and expect things to just work. They are not the same. This is especially true when you mix up your character encodings.
C# characters are not ASCII characters. They are Unicode characters, represented by Unicode code points. When you then turn around and write those characters out, you need to specify what kind of data to write out. When you read your byte array into a string, using Encoding.GetEncoding(1252), you are getting the characters corresponding to code page 1252, in which 0xdc is a Ü.
But when your string is being converted back into bytes to send over the network, it is being written out as UTF-8. In UTF-8, UTF-00DC cannot be encoded as a single byte, since that byte value is used to indicate the start of a multi-byte sequence. Instead, it's encoded as the multi-byte sequence 0xc3 0x9c. As far as C# is concerned, those two values are the same character. (I don't know where that extra 0x0a is coming from, but my guess is an errant line feed from one of your text boxes and/or some other part of your process).
Its not clear what exactly you're trying to do, but I suspect you are converting way too many times for it to work out correctly. If you know the byte sequence you want to send, why not just encode that as a byte[] directly? For example, use a MemoryStream and write the constant bytes you need into it.
To get the values out of your text boxes, your original code to "convert" the string of hex digits into a string of ASCII characters had the right idea. You just need to stop at the point where you have a byte array, since ultimately the byte array is what you want.
public byte[] GetBytesFrom(string hex)
{
var length = hex.Length / 2;
var result = new byte[length];
for (var i = 0; i < length; i++)
{
result[i] = byte.Parse(hex.Substring(i, 2), NumberStyles.HexNumber);
}
return result;
}
// Variable portions of packet structure.
var byte[] segment2 = GetBytesFrom(textbox1.Text);
var byte[] segment4 = GetBytesFrom(textbox2.Text);
var byte[] segment6 = GetBytesFrom(textbox3.Text);
MemoryStream output = new MemoryStream();
output.Write(new[] { 0x00, 0x38, 0x60, 0xdc, 0x00, 0x00 }, 0, 6);
output.Write(segment2, 0, segment2.Length);
output.Write(new[] { 0x00, 0x00, 0x00, 0x20 }, 0, 4);
output.Write(segment4, 0, segment4.Length);
output.Write(new[] { 0x00, 0x06 }, 0, 2);
output.Write(segment6, 0, segment6.Length);
From here, you could use MemoryStream.CopyTo() to copy it to another stream, or MemoryStream.Read() to read the entire packet into a new byte array, or MemoryStream.GetBuffer() to get the underlying buffer (though that last one is rarely what you want -- it includes unused padding bytes)