2

I have a problem in my C# program. I am currently developing a gateway (both TCP and UDP protocols), and have to log the traffic to a file. I got some test data to try my gateway with. Example data: ASYRE\x00\x00\x01.

My program should log this into a file, and here comes my problem: When logging to the file (or writing it onto the Console) i get ASYRE, and the special \x00\x00\x01 characters will be decoded in the file, however, i have to log them as they came in, so when logging they should be "ASYRE\x00\x00\x01".

I tried using Encoding.Default.GetString(), Convert.ToString(), Parse and even Regex, but I don't know how to get it to be logged correctly.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Malathiane
  • 31
  • 4
  • Maybe this can help? https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa – sorioli computec Dec 06 '21 at 11:31
  • Hi, could you show how you save and read data? If you use text editors to see what data is being written they probably will not display raw bytes correctly. Is the output binary data - then you'd need to _read_ it as binary. – oleksii Dec 06 '21 at 11:34
  • The data comes in through the network from a client written in Python, where it is like this: msg1 = b'ASYRE\x00\x00\x01' In the Python program's logger there is no problem to log it as it goes out: 127.0.0.1:53760 -> 127.0.0.1:1002 (8b) b'ASYRE\x00\x00\x01' (from the Python log file) I recieve the program on in my C# program through sockets: `int len; len = stream.Read(message, 0, message.Length); byte[] msg = new byte[len]; Array.Copy(message, msg, len);` – Malathiane Dec 06 '21 at 11:45
  • 1
    Consider displaying the bytes [in hex](https://stackoverflow.com/a/2426258/17034). – Hans Passant Dec 06 '21 at 11:52
  • what happens when someone sends `Renée` ? Will it output `Renée` or will it output `Ren\xc3\xa9e` (or something else...) ? – Luuk Dec 06 '21 at 12:03

2 Answers2

3

You are looking for a string Dump, which you can implement with a help of Linq:

using System.Linq;

...

private static string Dump(string value) {
  if (null == value)
    return "[null]";

  return string.Concat(value.Select(c =>
      c < ' ' ? $"\\x{(int)c:x2}"
    : char.GetUnicodeCategory(c) == UnicodeCategory.Format ? $"\\u{(int)c:x4}"
    : c.ToString()));
}

If you want a solution without Linq, have a look at StringBuilder:

private static string Dump(string value) {
  if (null == value)
    return "[null]";

  StringBuilder sb = new StringBuilder();

  foreach(char c in value) 
    if (c < ' ')
      sb.Append($"\\x{(int)c:x2}");
    else if (char.GetUnicodeCategory(c) == UnicodeCategory.Format) 
      sb.Append($"\\u{(int)c:x4}");
    else
      sb.Append(c);

  return sb.ToString(); 
}

Demo:

Console.Write(Dump("ASYRE\x00\x00\x01"));

Outcome:

ASYRE\x00\x00\x01
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

Something short that assumes you're working with ASCII

byte[] input = { 65, 83, 89, 82, 69, 0, 0, 1 };
var output = string.Concat(input.Select(b => b < 32 ? $"\\x{b:X02}" : Encoding.ASCII.GetString(new byte[] {b})));
System.Console.WriteLine(output);

prints ASYRE\x00\x00\x01

Hans Kilian
  • 18,948
  • 1
  • 26
  • 35