Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add hexadecimal from file to List<byte>

Tags:

arrays

c#

hex

byte

I'm trying to make a List<byte> from a file that contains string (Hexadecimal) . the definition is :

List<byte> myArray = new List<byte>();

if I want to add my information directly I use something like this :

  myArray.Add(0xb8);

Note : Without any quotation or double-quotation .

The problem is when I want to do the same thing from file! Now I want to know what 0xb8's type is so I use the following code :

0xc3.GetType().ToString()

the result is : System.Int32 !!!!

but when I read strings from a file and use code like this , it give me the following error .

code :

 Line = "0xb8";
myArray.Add(Convert.ToInt32(Line));

Error :

Argument 1: cannot convert from 'int' to 'byte'

and it's clear . because the only overload of myArray gets only a byteas argumant. What makes thing so complicated for me is why it doesn't give me any error when I add a Int32 to myArray in myArray.Add(0xb8); .

I think it should be a form of byte ! maybe !

Why doesn't it give any errors and how can accomplish this scenario (I mean add byte from string to myArray ) ?

like image 444
Mohammad Sina Karvandi Avatar asked Jun 16 '15 10:06

Mohammad Sina Karvandi


3 Answers

This works:

var list = new List<byte>();

byte byteValue = 0xb8;
list.Add(byteValue);

This doesn't ("cannot convert from 'int' to 'byte'"):

var list = new List<byte>();

int byteValue = 0xb8;
list.Add(byteValue);

Yet in both cases 0xb8 is recognized as System.Int32. So why does the compiler allow implicit conversion of an int to byte in the first example?

See C# spec 6.1.9 Implicit constant expression conversions:

A constant-expression (§7.19 [including literals]) of type int can be converted to type sbyte, byte, short, ushort, uint, or ulong, provided the value of the constant-expression is within the range of the destination type.

This exists because all integer literals are either (u)int or (u)long, as specified in 2.4.4.2 Integer literals.

Given 0 <= 0xb8 <= 255, the compiler allows the implicit conversion.

In your case, because of reasons explained by @usr, you'll need to do an explicit conversion:

myArray.Add((byte)Convert.ToInt32(Line, 16));
like image 147
CodeCaster Avatar answered Nov 11 '22 11:11

CodeCaster


0xb8 is an integer literal (like 1234). "0xb8" is a string literal (like "x"). There is no such thing as a hex literal in C#. It's an int literal in hex format. So that explains the trouble you had with the literals.

Not all of the string parsing functions support hex input. See this for how to parse a hex string.

When a parsing function gives you an int and you need to treat it as a byte, you can cast: (byte)myInt. This is safe because the parsed value is guaranteed to fit into a byte.

In some places the compiler is able to convert automatically for you if you have been using a constant such as 0xb8. Since you will not have that in practice (you are parsing a file) that case is not relevant for the final code. But this explains why that works.

like image 41
usr Avatar answered Nov 11 '22 11:11

usr


You can get rid of that compiler error by just casting the value to byte:

myArray.Add((byte)Convert.ToInt32(Line));

However, when you run that code you will get a different error:

Unhandled Exception: System.FormatException: Input string was not in a correct format.

That's because the Convert.ToInt32 method doesn't parse hexadecimal numbers out of the box.

You can specify the base when you convert the string to a number:

myArray.Add((byte)Convert.ToInt32(Line, 16));
like image 23
Guffa Avatar answered Nov 11 '22 11:11

Guffa