I'm reading a hex byte array from a file using an instance of the BinaryReader class, and I need to decode it from UTF-16. From what I know, I need to do this using System.Text.Encoding.Unicode.GetString(byte[] array).
This is what my code looks like:
public static string ReadHex(string path, Int32 startOffset, Int32 endOffset, bool decode, bool utf16)
{
if (!File.Exists(path))
{
throw new FileNotFoundException($"Could not find a file in path {path}");
}
string result = "";
List<byte> bytes = new List<byte>();
BinaryReader br = new BinaryReader(File.OpenRead(path));
for (int i = startOffset; i < endOffset; i++)
{
br.BaseStream.Position = i;
bytes.Add(br.ReadByte());
}
br.Close();
if (decode && utf16)
{
result = System.Text.Encoding.Unicode.GetString(bytes.ToArray());
}
else if (decode)
{
result = System.Text.Encoding.UTF8.GetString(bytes.ToArray());
}
else
{
foreach (byte b in bytes)
{
result += b.ToString("X2");
}
}
return result;
}
It reads the given hex offsets provided by the parameters and decodes them if wanted. The UTF-8 part works perfectly, giving me valid decoded strings. But my issue is with the UTF-16 part.
This is the data that is read from the file:
4D 00 6F 00 6A 00 61 00 6E 00 67 00 20 00 41 00 42
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00
In theory, this is what should be outputted:
Mojang AB
It kinda works, but with one oddity, this is what is outputted when writing the string that the method returns:
Mojang AB ?
These question marks appear on anything that's UTF-16 I put into the method. I don't understand why they appear, as the data that was passed into System.Text.Encoding.Unicode.GetString(byte[] array) does not contain anything past the string it's supposed to contain, and is made up of zeroes (00). Anyone have an idea on why this is happening?
Related
I am debugging some code right now (VS 2019, .NET Framework 4.7.2), stopped at a breakpoint, using the Immediate Window to evaluate variables. I have a BitVector32 which I am not understanding its state. Here is the content of the IW:
stillInHand.ToString()
"BitVector32{00000000000000000000000000001100}"
stillInHand
{BitVector32{00000000000000000000000000001100}}
Data: 12
stillInHand[0]
true
stillInHand[1]
false
stillInHand[2]
false
stillInHand[3]
false
stillInHand[4]
true
stillInHand[5]
false
stillInHand[6]
false
stillInHand[7]
false
There have been no calls to any of the Create* methods, and stillInHand was created with the BitVector32(Int32) ctor. Shouldn't indices 2 & 3 be true and all the rest be false?
Actually, this issue is related to the understanding of the index of BitVector32[ ].
First of all, stillInHand[1] doesn’t mean to get the second bit of stillInHand(BitVector32). It represents this action: use 00 00 … 00 01 to perform &(AND) operation with stillInHand(BitVector32).
For an example: stillInHand(BitVector32) is 00 00 00 00 00 … 00 00 00 11 00, and 1 is 00 00 00 00 00 … 00 00 00 00 01. Then perform &(AND) operation.
00 00 00 00 00 … 00 00 00 11 00 12 &(AND)
00 00 00 00 00 … 00 00 00 00 01 `1`
--------------------------------------------
00 00 00 00 00 … 00 00 00 00 00
And you can see that the last bit(focus on the index value 1) changes from 1 to 0, so the result will be false, if you output or see the result of stillInHand[1].
So, for stillInHand[2], you can see
00 00 00 00 00 … 00 00 00 11 00 12 &(AND)
00 00 00 00 00 … 00 00 00 00 10 2
--------------------------------------------
00 00 00 00 00 … 00 00 00 00 00
The second to last bit(focus on the index value 2) changes from 1 to 0, so the result will be false too.
And for stillInHand[8], you can see
00 00 00 00 00 … 00 00 00 11 00 12 &(AND)
00 00 00 00 00 … 00 00 00 10 00 8
--------------------------------------------
00 00 00 00 00 … 00 00 00 10 00
The fourth to last bit(focus on the index value 8) doesn’t change and it remains as 1, so the result will be true.
Actually, if you analyze the source code from here: Reference Source, you can see these codes:
/// <devdoc>
/// <para>Gets or sets a value indicating whether all the specified bits are set.</para>
/// </devdoc>
public bool this[int bit] {
get {
return (data & bit) == (uint)bit;
//clear other bits (to 0) through the AND operation of the data and mask.
//If the result of the operation is equal to the mask, return true.
//Otherwisse, return false.
}
set {
if (value) {
data |= (uint)bit;
//data = data OR mask, set the specified bit to “1”
}
else {
data &= ~(uint)bit;
//data = data AND ~mask, set the specified bit to “0”
}
}
}
Of course, you can consider it as mask, and this will be easy to understand.
I have this code which generate 80 bytes of word 'Administrator' to bellow output.
szOperatorName = BitConverter.ToString(data, 45, data.Length - 45); //szOperatorName is set to 'Administrator'
byte[] OperatorName = new byte[80];
Array.Copy(Encoding.ASCII.GetBytes(szOperatorName), OperatorName, System.Math.Min(80,szOperatorName.Length));
OUTPUT
41 64 6D 69 6E 69 73 74 72 61 74 6F 72 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
EXPECTED OUTPUT
41 00 64 00 6d 00 69 00 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 6f 00 72 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
I have highlighted some of main deference between two, any help on getting expected result will be much appreciated
To get expected output use Unicode encoding to get bytes
Encoding.Unicode.GetBytes(szOperatorName)
Test
byte[] bytes = System.Text.Encoding.Unicode.GetBytes("Administrator");
foreach (var b in bytes)
Console.WriteLine(b);
. . . .
Array.Copy(bytes, newArr, bytes.Length);
your current output is based on ASCII encoding (obviously)
I am trying to compare Finger print string & GPS data by converting byte array but result are not working for same finger record from different ends.
Here is my string/hex values from finger scan device & GPS accordingly.
Finger print encoded result as below.
AwFZFo4A//7//vAA4ACAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSDRiePJYW3mEcxF5jKZueCSwPPiitjx4atw0+KT7LvimYFd9IIFe/diDbN1yihb91sAffQLoKnzsgbNw+JxT8OqmR/T+wThpGMkpWNSFU90mxyBcspZJSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMBWRqRAP/+/wLgAMAAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMZMXXlcZhF5SoAYeWKXbnh8qTx4RtA1eILsLfm8TWj8eFJWfPp0XX2sdWx9xI4cfa6wHvze2Cl8QQEyfdMBfvzCdbLpCQWMSQz6K8yGjEnY0pBT0MKZRlSQfa9I5rkySLB6V8yKg1FMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
GPS Tracker sending in HEX Code as below
03 01 5A 16 96 00 FF FE E0 02 C0 00 80 00 80 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 32 0B 16 9E 59 91 03 FE 6D 15 1A BE 55 98 85 7E 5D 9E 5B 7E 3A A5 0E 1E 16 2C 8C BE 25 B2 8B 1E 1E 0D 95 5F 75 9A C6 B7 24 23 8E BF 70 A3 87 7F 3B AE 49 FF 16 B7 8B DF 36 91 00 1C 41 14 56 FC 3D 91 16 9A 37 9D 14 F8 33 1F 92 19 30 16 2C 56 24 1C 12 36 2C 17 55 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
How to compare both with byte array??
Finger print code required to Convert FromBase64 string to Byte and GPS code required to Hex to byte..
I am getting different array size from Finger print it returning 512 byte array and from GPS it comes 256 byte array..
below is my code form C#
Create demo aspx page and check it.
I have added Demo project here.
you can download and check it..
http://maplayout.com/demo.zip
Thanks
Abhi
I have been resolved issue by converting HEX Code string to Byte[] and
USB reader value convert fromBase64 string then Byte[]
I have created below method to Compare both with byte[],
below fpengine is the thirdparty COM Object that will use for compare finger scanned value with finger point algorithm.
public bool IsMatchFound(string HexCodeString , string USBReaderString)
{
try
{
int scope = 0, intdisc=0;
byte[] gmat = HexEncoding.GetBytes(HexCodeString, out intdisc); //StringToByteArray(str1);
byte[] gref = Convert.FromBase64String(USBReaderString);
scope = fpengine.MatchTemplate(gmat, gref);
return (scope > 30) ? true : false;
}
catch (Exception ex)
{
return false;
}
}
Let me know if anybody want help same kind of application..
So I'm trying to send a (string?) of hex that looks like this "7E 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 FF" over a serial port. My code looks like this:
serialport.write("7E 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 FF");
The controller that is receiving it is not acknowledging this data, I'm assuming that the character encoding of the serial port which defaults to ASCII is an issue. How would I go about fixing this?
I take it that you are using the SerialPort Class, right?
Then, I think you want to parse your string, convert the hex values to bytes and then write the bytes directly.
I'm thinking something like this:
string str = "7E 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 FF";
byte[] bytes = str.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
serialport.Write(bytes, 0, bytes.Length);
The value 0xFF is used to signify UART Rx buffer empty, and therefore the need to convert to representative ASCII bytes over conventional serial to avoid this value.
I have data in the form of from TextBox1
00 00 00 4E FF 53 4D 42 25 00 00 00 00 18 01 28 ...N.SMB%......(
00 00 00 00 00 00 00 00 00 00 00 00 00 08 12 8B ................
01 08 7E 31 11 00 00 05 00 00 00 00 00 00 00 02 ..~1............
and I tried to change it to be like this on the result TextBox2
...N.SMB%......(
................
..~1............
I've tried the function *. remove but only the first row are deleted but the second line and so on are not deleted. Can anybody help me?
i use this code
string test = rtText1.Text;
rtText2.Text = test.Remove(0, 48);
and then this result rtText2
...N.SMB%......(
00 00 00 00 00 00 00 00 00 00 00 00 00 08 12 8B ................
01 08 7E 31 11 00 00 05 00 00 00 00 00 00 00 02 ..~1............
how can I make a command "test.Remove (0, 48);" can be done on each line? or is there another function?
It's hard to say exactly what you need based on what you've posted, but a regex may work well here:
TextBox2.Text = System.Text.RegularExpressions.Regex.Replace(
TextBox1.Text,
#"^.{49}",
"",
RegexOptions.Multiline );
This will simply replace the first 49 characters of each line with an empty string.
It looks to me as though you're trying to remove the hexadecimal representation of whatever string is on the right.
This did the trick for me:
// Initial data
string Data = #"00 00 00 4E FF 53 4D 42 25 00 00 00 00 18 01 28 ...N.SMB%......(
00 00 00 00 00 00 00 00 00 00 00 00 00 08 12 8B ................
01 08 7E 31 11 00 00 05 00 00 00 00 00 00 00 02 ..~1............";
// An array containing each line of data
string[] lines = Data.Split('\n');
Data = "";
// Loop for each line, removing each "byte" + it's space, plus the trailing space
for (int i = 0; i < lines.Length; i++)
{
Data += lines[i].Remove(0, (3 * 16) + 1);
if (i != lines.Length - 1)
Data += "\r\n";
}
Console.Write(Data);
And here is the output:
...N.SMB%......(
................
..~1............
ideone link