0

In short, I am using C# and I have some strings like:

00 fe ff 01 ff ff ff 01 00 01 00 00 02 01 00 ff 54 5b

or without spaces:

00feff01ffffff0100010000020100ff545b

I would like these to be formatted as hex values like the following string:

\x00\xfe\xff\x01\xff\xff\xff\x01\x00\x01\x00\x00\x02\x01\x00\xff\x54\x5b

I have spent today trawling through StackOverflow and some other places and tried a number of things, but I can't seem to get my output string formatted in this way when using variables.

Just to elaborate on the variables I would use to make up this string:

string maincode = "00feff01ffffff0100010000020100";
string parameter = "ff";
string checksum = "545b";
//this is to put the three variables back together as a single string after all calculations are complete. Will display as this 00feff01ffffff0100010000020100ff545b
string output = maincode + parameter + checksum;

From the output variable step, I then need to add the \x before every byte to format a string that will be in hex format to send to the device I am controlling.

JMP
  • 4,417
  • 17
  • 30
  • 41
JasonW
  • 1
  • It would be better if you can generate the string like that in the first place. Would that be possible? – ProgrammingLlama Oct 21 '20 at 06:37
  • If I knew how then I am sure that this would be fine to do in the first instance. I am new to C# and have spent a lot of time over the last few years in LUA, so I am struggling with the syntax a bit at the moment! Basically, the string is going out as ASCII characters and putting a \x in front of each "hex byte" is causing \x to be displayed as ASCII as well. I need each byte to be converted to an actual HEX byte of the same value as it's shown in the strings above. eg. ff needs to be displayed in my result as ascii ÿ – JasonW Oct 21 '20 at 07:38
  • I can get the fixed string of "\x55\xaa\x00" to display on the output screen as Uª0, but I can't work out how to get my variables with text representation of the hex byte to be converted into a hex value. – JasonW Oct 21 '20 at 07:41
  • 1
    Your comment got me thinking more about the command formatting. As I was changing the string hex bytes into integers for the checksum calculation, I then used the Convert.ToChar command to create a string of ASCII characters. Once this was complete I have been able to successfully send these strings to the device I was trying to control. Thanks for shoving me in the right direction. This thread helped me flesh out the idea of using some of the processes I already had https://stackoverflow.com/a/25558610/14489779 – JasonW Oct 21 '20 at 10:51

5 Answers5

0

I'm not sure, I get correctly, what you neeed, but here's my idea.

var result = string.Empty;
for (var i = 0; i < output.Length; i += 2)
{
    result += string.Format(@"\x{0}{1}", output[i], output[i + 1];
}

Be adviced - I wrote it out of my head, so may have some spelling errors, but should be some good starting point for you :-)

  • I couldn't get this to work, but as mentioned in my replies above, I am only 2 days into c# programming. I am assuming the issues are mine! I will have to have a play with this code to get my head around it and see if it does what I want down the track when I understand C# more. For now I think I have a solution creating strings of ascii characters converted from the integers I have converted from the string hex bytes! It's a long roundabout process, but my program is controlling the device I have been trying to control, so I think I'll run with that for now. Thanks for your suggestion. – JasonW Oct 21 '20 at 10:59
0

Pretty simple string manipulation

str = "\\x" + str.Replace(" ", "\\x");

Austin G
  • 136
  • 1
  • 7
  • Thanks for the suggestion. This is a cool way to substitute things in strings, but unfortunately it's not what I am after. I need to be able to convert 00 in the string format to be a hex value of 00, which is the ascii code of , 01 to be and so on. At this stage I have ASCII strings, which I believe "00" would be sending \x30\x30 to the device I am trying to control. – JasonW Oct 21 '20 at 10:44
  • @JasonW That is a little different than what you asked. I think what you are looking for can be found at https://stackoverflow.com/questions/2972103/how-to-convert-a-string-to-a-hex-byte-array – Austin G Oct 21 '20 at 23:49
0

Update

Seems you are just trying to convert a hex string to a bye array

Linq appoach

string output = maincode + parameter + checksum;

var result = Enumerable.Range(0, output.Length)
        .Where(x => x % 2 == 0)
        .Select(x => Convert.ToByte(output.Substring(x, 2), 16))
        .ToArray();
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • Thanks for your suggestions. I tried each of these, but I don't think I understood them correctly as I kept getting errors with each one in my program. I'll check back over these suggestions once I spend some more time with C# and see if I can get any of them to work in my programs more efficiently than the hack way I got my working result. – JasonW Oct 21 '20 at 11:01
  • @JasonW updates, which should convert to a byte array with your intended bytes – TheGeneral Oct 21 '20 at 11:21
0

In .NET Core we can do this very efficiently using string.Create(). I.e. no extra allocations, in contrast to the other proposed solutions.

The method below correctly (and efficiently) handles arguments with spaces. E.g. these inputs yield correct result:

  • "00 fe ff 01 ff ff ff 01 00 01 00 00 02 01 00 ff 54 5b"
  • "00feff01ffffff0100010000020100ff545b"

Sample code

public static string Hexify(string s)
{
    // NOTE: See remarks!
    // var length = (s.Length - SpaceCount(s)) * 2;
    var length = s.Length * 2;
    
    return string.Create(length, s, (chars, state) =>
    {
        int i = 0;
        int j = 0;
        while (i < state.Length - 1)
        {
            if (state[i] == ' ')
            {
                i++;
                continue;
            }

            chars[j++] = '\\';
            chars[j++] = 'x';
            chars[j++] = state[i++];
            chars[j++] = state[i++];
        }
    });
}

Remarks

Note that the length of the resulting string can vary, depending on spaces. If the length of the result is important (i.e. trailing NUL characters are not accepted) you need to know before-hand which of the two input formats you are dealing with. Then simply implement SpaceCount() and use it as shown above.

l33t
  • 18,692
  • 16
  • 103
  • 180
  • I tried this code, but I am assuming I needed to include .NET core in my program? I am really new to C# (started yesterday) and have done little C language programming in the past, so please forgive my ignorance! I had a lot of errors when I simply copied and pasted it into my project. – JasonW Oct 21 '20 at 10:54
  • The above code only works in `.NET Core`. If you target `.NET Framework` you will have to go with less optimal variants. You can choose between the two when you first create a project. Also, if you're new to `C#` then I suggest you experiment a bit to solve the task. You don't necessarily need the most optimized method available :P – l33t Oct 21 '20 at 11:19
  • I had spent the last two days experimenting, mainly on understanding how to format float values so they aren't seen as integers, then this formatting of hex vs ascii values. It was once I finally got frustrated that I decided to reach out :) I am normally a very patient person, so it takes a lot of testing different things before I actually ask for help. At least now I know how I can get my project working by converting to ASCII characters then I can now re-write my code into more efficient chunks. – JasonW Oct 21 '20 at 22:04
0

Tested with Raspberry pi UARTS


This code was tested with device which has the same requiremnt as yours hat need to have string with "\Xxx" syntax and it works with the below sample code.

    string decString = "test1"; // any message 
    byte[] bytes = Encoding.ASCII.GetBytes(decString);// converting message string to ASCII HEX
    string hexString = BitConverter.ToString(bytes);
    hexString = hexString.Replace("-", "");
  

    var convert = string.Empty;
    for (var i = 0; i < hexString.Length; i += 2)
    {
        convert += string.Format(@"\x{0}{1}", hexString[i], hexString[i + 1]);
    }


    Console.WriteLine(result);
}
Kosala M
  • 1
  • 1