Vivian
Vivian

Reputation: 1061

How to set hex entry ranges for different segments in a data message?

A 24 hex byte message entries: xx xx xx xx xx xx xx xx xx xx xx xx

I have a 24 hex byte message entry into a textbox with different byte segment entry requirements, is there a template code for me to code dynamically the range of hex value I require for each segment e.g. 1, 4?

I tried the code below but is not what I wanted as it converts whole hex entry into int equivalent without giving me the freedom to code the range I wanted.

outputTxt.Text = String.Join(" ", 
    hexTextBox.Text.Trim().Split(' ').Select(item => Convert.ToInt32(item, 16)));

For example, the first group of 2 hex value entered into the textbox, a function to check hex value entered is between 0 to 100 in uint before converting it into its decimal equivalent onto the output textbox, else it will display 'Error' display on the output textbox.

Subsequently the next 4 bytes, I only allow 4 bytes of hex entries in the range between -1000 to 1000 in int else display 'error' message.

EDIT: Sorry for the confusion for how I phrase my sentences previously, for the 5 bytes is just a byte representation of a ASCII character for each byte with range of 0 to 255. How to code these different cases? Thanks!

uint value1 = reader.ReadByte(); // 1 byte.
    if (value1 ==700)
    {
                   OutputTxt.Text = value1.ToString();
                   OutputTxt.Text +="\n";
    }
    else
    {
                OutputTxt.Text = "Error"
                OutputTxt.Text +="\n";
    }

   uint value2 = reader.ReadByte(); // 1 byte.
    if (value2 <=1000)
    {
                   OutputTxt.Text += value2.ToString();
                   OutputTxt.Text +="\n";
    }
    else
    {
                OutputTxt.Text += "Error"
                OutputTxt.Text += "\n";
    }

I know this might be simple bug but I can't figure out the correct syntax to prevent re-updating my first byte textbox after running second readByte() validation?

Upvotes: 4

Views: 325

Answers (1)

Matthew Watson
Matthew Watson

Reputation: 109537

I think your best bet is to do something like this:

  1. Convert the hex string into an array of bytes.
  2. Use MemoryStream to wrap the array and pass it to a BinaryReader to allow easier reading of the data.
  3. Write a custom method that reads the required values from the stream and validate the values read.

The only tricky bit is parsing a set of bytes that isn't the normal size for an integral type, for example 5 bytes.

The solution for that case is to prefix the 5 bytes with 3 zero bytes and then use BitConverter to turn that into a long. For example:

public static long LongFromBytes(byte[] bytes)
{
    // This uses little-endian format. If you're expecting bigendian, you
    // would need to reverse the order of the bytes before doing this.

    return BitConverter.ToInt64(bytes.Concat(new byte[8-bytes.Length]).ToArray(), 0);
}

A suitable method to convert your hex string (with spaces) into a byte array is:

public static byte[] StringToByteArray(string hex)
{
    hex = hex.Trim().Replace(" ", "");

    return Enumerable.Range(0, hex.Length)
        .Where(x => x % 2 == 0)
        .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
        .ToArray();
}

Now you can put these things together to validate the values in your hex string:

string hexString = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18";

using (var stream = new MemoryStream(StringToByteArray(hexString)))
using (var reader = new BinaryReader(stream))
{
    int value1 = reader.ReadByte(); // 1 byte.
    Console.WriteLine(value1);

    int value2 = reader.ReadByte(); // 1 byte.
    Console.WriteLine(value2);

    int value3 = reader.ReadInt32(); // 4 bytes.
    Console.WriteLine(value3);

    long value4 = LongFromBytes(reader.ReadBytes(5)); // 5 bytes into a long.
    Console.WriteLine(value4);
}

Once you've read the values, you can validate them as required.

Upvotes: 3

Related Questions