2

So someone took int value, converted it to string then converted it to ASCII values and then finally to byte[] with inconsistent length 1 - 4 bytes.

e.g. 100 -> "100" -> { 49, 48, 48 }.

Now I need that int value and I did it like this:

{ 49, 48, 48 } -> '1' + '0' + '0' -> "100" -> 100

                switch (header[25].Count)
                {
                    case 1:
                        hex = "" + (char)header[25][0];
                        amountOfData = Convert.ToInt32(hex, 16);
                        break;

                    case 2:
                        hex = "" + (char)header[25][0] + (char)header[25][1];
                        amountOfData = Convert.ToInt32(hex, 16);
                        break;

                    case 3:
                        hex = "" + (char)header[25][0] + (char)header[25][1] + (char)header[25][2];
                        amountOfData = Convert.ToInt32(hex, 16);
                        break;

                    case 4:
                        hex = "" + (char)header[25][0] + (char)header[25][1] + (char)header[25][2] + (char)header[25][3];
                        amountOfData = Convert.ToInt32(hex, 16); ;
                        break;

                    default:
                        break;
                }

but maybe there is better solution...

EDIT: sorry for not mentioning that, but header is List<List<byte>>

7
  • int result = array.Aggregate(0, (s, a) => s * 10 + a - '0'); Commented May 9, 2022 at 7:46
  • 1
    what is the type of header[25]? is it a byte[]? a List<byte>? or...? Commented May 9, 2022 at 7:57
  • sorry for not mentioning that, but header is List<List<byte>> Commented May 9, 2022 at 8:01
  • and now I realized that I know one of the dimensions needed so it's List<byte>[] but it doesn't matter Commented May 9, 2022 at 8:06
  • side note: List<byte> seems like a very unusual choice here; not saying it is "wrong" as such - just: very unusual Commented May 9, 2022 at 8:08

2 Answers 2

2

You can use library functions to parse from byte-like data to primitives; you're talking about ASCII, which means that Utf8Parser will work fine for us (all ASCII is also valid UTF8, although the reverse is obviously not true); normally, we would expect that header[25] is a byte[], a segment there-of, or some other raw binary source, but: ultimately, something like:

var span = new ReadOnlySpan<byte>(header[25], 0, header[25].Count);
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
    ThrowSomeError(); // not an integer

If header[25] is something less convenient (like a List<byte> - I notice that in your example, your header[25] has a .Count not a .Length, which suggests it isn't a byte[]), then you can always either stackalloc a local buffer and copy the data out, or you can peek inside the list with CollectionMarshal.AsSpan<T>(List<T>), which returns a Span<T> from the underlying data:

var span = CollectionMarshal.AsSpan(header[25]);
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
    ThrowSomeError(); // not an integer

As a runnable example that just shows the API:

using System;
using System.Buffers.Text;

Span<byte> span = stackalloc byte[]  { 49, 48, 48 };
if (!Utf8Parser.TryParse(span, out int amountOfData, out _))
    throw new FormatException();
Console.WriteLine(amountOfData); // 100
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot. I tried your code and came to this solution with its help: int amountOfData = Convert.ToInt32(Encoding.ASCII.GetString(header[25].ToArray()), 16);
Actually I came to this ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(header[25].ToArray(), 0, header[25].Count); Utf8Parser.TryParse(span, out int amountOfData2, out _);, but it returned 44 from { 52, 52, 68 } and not 44D as it should
@Imm in the original question, you were trying to parse an integer; if you are now dealing with strings, then that's just anyEncoding.GetString; in modern runtimes, the API accepts spans. For example, Encoding.UTF8.GetString(span)
oh, right, sorry about that, I overlook this fact even though it was in my original solution
2

You can use the Encoding/GetString method to convert bytes of different encodings (e.g. ASCII in your case) to a .NET string:

var input = new byte[] { 49, 48, 48 };
var str = Encoding.ASCII.GetString(input);
var result = int.Parse(str, NumberStyles.None, CultureInfo.InvariantCulture);

1 Comment

you can bypass the string step to avoid some overheads, btw (see my answer)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.