Home > database >  TypeConversion of a string to bytearray
TypeConversion of a string to bytearray

Time:11-02

I have a string value:

Example:

string msg = "array('B', [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0,
 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2,
2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6,
7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11,
12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2,
5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10])"

I want to convert this string value to type byte[].

private byte[] data;
//after type conversion from string to byte array
Debug.Log("data in byte array is: "   data);

Output should be:

data in byte array is: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7, 9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10, 10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]

Since the actual string msg is a very large value, I want to do this with minimum execution time possible.

CodePudding user response:

Looks like a fairly simple parsing problem. We could run up a full parser for the format, but that's probably well beyond your needs.

Let's assume instead that your msg is always going to be in the format shown, starting with "array('B', [", ending with "])" and having 0 or more comma-separated decimal values. Since any option you choose is going to scan the string at least once, we can design code around doing exactly that.

The actual content contains only 4 types of characters:

  • digit (0-9)
  • comma (,)
  • space ( )
  • end-array (])

We can iterate through the characters starting at the first character after the start-array ([ at offset 11) and do something with each of those character types: ignore it, update the current value, yield the current value and/or exit.

If all of the assumptions are correct then this is a simple process. One scan through the characters, no allocations in the parser itself. Here's a sample:

IEnumerable<byte> ParseArrayMsg(string msg)
{
    if (!msg.StartsWith("array('B', [") || !msg.EndsWith("])"))
        yield break;
    
    int value = 0;
    for (int i = msg.IndexOf('[')   1; i < msg.Length; i  )
    {
        var c = msg[i];
        if (c == ',' || c == ']')
        {
            yield return (byte)value;
            value = 0;
            if (c == ']')
                break;
        }
        else if (char.IsDigit(c))
            value = value * 10   (int)(c - '0');
        else if (c != ' ')
            throw new Exception($"Invalid character '{c}' at index '{i}'.");
    }
}

The returned enumerable can then be processed however you like.

Your code won't actually produce the output you want, but this will:

var data = ParseArrayMsg(msg).ToArray();
Console.WriteLine($"Data in byte array is: [{string.Join(", ", data.Select(b => b.ToString()))}]");
Data in byte array is: [255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 0,
0, 1, 0, 1, 0, 0, 255, 219, 0, 67, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2,
2, 4, 3, 2, 2, 2, 2, 5, 4, 4, 3, 4, 6, 5, 6, 6, 6, 5, 6, 6, 6, 7, 9, 8, 6, 7,
9, 7, 6, 6, 8, 11, 8, 9, 10, 10, 10, 10, 10, 6, 8, 11, 12, 11, 10, 12, 9, 10,
10, 10, 255, 219, 0, 67, 1, 2, 2, 2, 2, 2, 2, 5, 3, 3, 5, 10, 7, 6, 7, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10]

CodePudding user response:

You can try like the following:

    string yourString= "Your String";  
    // Convert a C# string to a byte array  
    byte[] bytes = Encoding.ASCII.GetBytes(yourString);  
  •  Tags:  
  • c#
  • Related