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>>
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);
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
Related
I have this code:
string result = "";
foreach(char item in texte)
{
result += Convert.ToString(item, 2).PadLeft(8, '0');
}
So I have string named result which is conversion of a word like 'bonjour' in binary.
for texte = "bonjour" I have string result = 01100010011011110110111001101010011011110111010101110010 as type integer.
And when I do
Console.writeLine(result[0])
I obtain 0, normal, what I expected, but if I do
Console.WriteLine((int)result[0])
or
Console.WriteLine(Convert.ToInt32(result[0]))
I obtain 48!
I don't want 48, I want 0 or 1 at the type integer.
Could you help me please?
You can just subtract 48 from it!
Console.WriteLine(result[0] - 48);
because the characters digits 0-9 are encoded as 48 to 57.
If you want to access each bit by index, I suggest using a BitArray instead:
var bytes = Encoding.ASCII.GetBytes("someString");
var bitArray = new BitArray(bytes);
// now you can access the first bit like so:
bitArray.Get(0) // this returns a bool
bitArray.Get(0) ? 1 : 0 // this gives you a 1 or 0
string a = "23jlfdsa890123kl21";
byte[] data = System.Text.Encoding.Default.GetBytes(a);
StringBuilder result = new StringBuilder(data.Length * 8);
foreach (byte b in data)
{
result.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
}
you can try this code.
Just Do this
Console.WriteLine(Convert.ToInt32(Convert.ToString(result[0])));
You're expecting it to behave the same as Convert.ToInt32(string input) but actually you're invoking Convert.ToInt32(char input) and if you check the docs, they explicitly state it will return the unicode value (in this case the same as the ASCII value).
http://msdn.microsoft.com/en-us/library/ww9t2871(v=vs.110).aspx
I have a byte array:
newMsg.DATA = new byte[64];
How can I convert it into binary value and then write it in text file with comma separation. Comma should be in between binary values not bytes.....
like 1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0.......
Here is an example that uses LINQ:
byte[] arr = new byte[] { 11, 55, 255, 188, 99, 22, 31, 43, 25, 122 };
string[] result = arr.Select(x => string.Join(",", Convert.ToString(x, 2)
.PadLeft(8, '0').ToCharArray())).ToArray();
System.IO.File.WriteAllLines(#"D:\myFile.txt", result);
Every number in byte[] arr is converted to a binary number with Convert.ToString(x, 2) and the comma "," is added between binary values with string.Join(",",...). At the end you can write all the elements in result to a text file by using System.IO.File.WriteAllLines.
The example above gives you this kind of output in a txt file:
0,0,0,0,1,0,1,1
0,0,1,1,0,1,1,1
1,1,1,1,1,1,1,1
...
Explanation of Convert.ToString(value, baseValue):
The first parameter value represents the number you want to convert to a string
and the second parameter baseValue represents which type of conversion you want to perform.
Posible baseValues are : 2,8,10 and 16.
BaseValue = 2 - represents a conversion to a binary number representation.
BaseValue = 8 - represents a conversion to a octal number representation.
BaseValue = 10 - represents a conversion to a decimal number representation.
BaseValue = 16 - represents a conversion to a hexadecimal number representation.
I think this will Help you c# provides inbuilt functionality to do so
with help of Convert.ToString(byte[],base); here base could be[2(binary),8(octal),16(HexaDecimal)]
byte[] data = new byte[64];
// 2nd parameter 2 is Base e.g.(binary)
string a = Convert.ToString(data[data.Length], 2);
StringBuilder sb = new StringBuilder();
foreach(char ch in a.ToCharArray())
{
sb.Append(ch+",");
}
// This is to remove last extra ,
string ans = sb.ToString().Remove(sb.Length - 1, 1);
This should get you going:
var bytes = new byte[] { 128, 255, 2 };
var stringBuilder = new StringBuilder();
for (var index = 0; index < bytes.Length; index++)
{
var binary = Convert.ToString(bytes[index], 2).PadLeft(8, '0');
var str = string.Join(",", binary.ToCharArray());
stringBuilder.Append(str);
if (index != bytes.Length -1) stringBuilder.Append(",");
}
Console.WriteLine(stringBuilder);
Say I have two byte arrays.
In the first scenario, I concatenate the two arrays (using Buffer.BlockCopy), then convert the result to base64 string.
In the second scenario, I convert each byte array into base64 string and then concatenate those strings.
Would the two results be the same?
Results would be the same if length of the first array is divisible by 3, in all other cases result of concatenation of two base64 strings would be different (and invalid base64) due to padding bytes at the end of first string. Length of second array does not matter for this operation as padding is always at the end.
Why "divisible by 3" - since base64 encodes every 3 bytes into exactly 4 characters arrays of such length will not need padding at the end. See https://www.rfc-editor.org/rfc/rfc4648#section-4 for formal details and https://en.wikipedia.org/wiki/Base64#Padding for more readable explanation.
I.e. if first array is 4 bytes long you get == at the end of converted string and concatenation with other base64 string will result in invalid base64 text
Convert.ToBase64String(new byte[]{1,2,3,4}) // AQIDBA==
Sample case where concatenation works the same on arrays first or on strings:
Convert.ToBase64String(new byte[]{1,2,3}) + // length divisible by 3
Convert.ToBase64String(new byte[]{4,5})
==
Convert.ToBase64String(new byte[]{1,2,3,4,5}) // AQIDBAU=
void Main()
{
byte[] bytes1 = new byte[]{10, 20, 30, 40, 0, 0, 0, 0};
byte[] bytes2 = new byte[]{50, 60, 70, 80};
Buffer.BlockCopy(bytes2, 0, bytes1, 4, 4);
PrintByteArray(bytes1);
string bytesStr = Convert.ToBase64String(bytes1);
Console.WriteLine(bytesStr);
string bytesStr1 = Convert.ToBase64String(bytes1);
string bytesStr2 = Convert.ToBase64String(bytes2);
string bytesStrMerged = bytesStr1 + bytesStr2;
Console.WriteLine(bytesStrMerged);
}
public void PrintByteArray(byte[] bytes)
{
var sb = new StringBuilder();
foreach (var b in bytes)
{
sb.Append(b + " ");
}
Console.WriteLine(sb.ToString());
}
Outputs:
10 20 30 40 50 60 70 80
ChQeKDI8RlA=
ChQeKDI8RlA=MjxGUA==
This is probably a very ridiculous question but I can't figure out how to import the user's input into a byte array. Since user input is always in a string format a conversation will be needed, however the numbers he entered must be the same in the array. For example:
Console.Write("Enter a number: ");
string text = Console.ReadLine();
/* Lets assume the user entered 22, 101, 1
How would I get those exact numbers in byte[]
*/
byte[] arr = new Byte[] {text};
UPDATED: what I am looking to get is
byte[] arr = new Byte[] {22, 101, 1};
Console.Write("Enter a number: ");
string text = Console.ReadLine();
byte[] byteArrayUTF= System.Text.Encoding.UTF8.GetBytes (text);
byte[] byteArrayASCII= System.Text.Encoding.ASCII.GetBytes (text);
You can find a better explanation here for the difference between UTF8 and ASCII
Unicode is a superset of ASCII, and the numbers 0–128 have the same
meaning in ASCII as they have in Unicode.
(From the updates)I think You are actually looking for converting the input string (comma separated values ) into an array of bytes. if so you can use thm Like the following:
string text = Console.ReadLine();
byte[] byteArr = text.Split(',').Select(x => Convert.ToByte(x)).ToArray();
This uses LINQ-to-Objects to "pipeline" from a string to an array of strings to a sequence of bytes to an array of bytes:
var arr = text
.Split(',')
.Select(digits => Byte.Parse(digits))
.ToArray();
While the other answers explain how to convert a string to a byte[],
I believe what you really want is to get the numbers into a byte[]
var input = "22, 101, 1";
var numbers = input.Split(',')
.Select(p => byte.Parse(p));
This will split the input at every , and convert each part to an integer.
You can use the GetBytes function to convert strings into bytes.
byte[] arr = Encoding.ASCII.GetBytes(text)
byte[] arr = System.Text.UTF8Encoding.UTF8.GetBytes(text)
byte[] arr = Encoding.Unicode.GetBytes(text)
If you are looking for a specific encoding type you can use the following to convert from other standard encoding types into what .NET provides.
byte[] arr = GetStringEncoding(StringEncodingType.CHARSET_UTF_16BE_CODEPAGE).GetBytes(text);
public static Encoding GetStringEncoding(StringEncodingType type)
{
switch (type)
{
case StringEncodingType.ASCII:
return Encoding.ASCII;
case StringEncodingType.Unicode:
return Encoding.Unicode;
//return Encoding.UTF7;
case StringEncodingType.UTF8:
return Encoding.UTF8;
//case StringEncodingType.CHARSET_UTF_16LE_CODEPAGE:// 1200, same as unicode
case StringEncodingType.CHARSET_UTF_16BE_CODEPAGE:// 1201,
case StringEncodingType.CHARSET_UTF_32LE_CODEPAGE:// 12000,
case StringEncodingType.CHARSET_UTF_32BE_CODEPAGE:// 12001,
case StringEncodingType.CHARSET_WINDOWS_1251_CODEPAGE:// 1251,
case StringEncodingType.CHARSET_WINDOWS_1252_CODEPAGE:// 1252,
case StringEncodingType.CHARSET_WINDOWS_1253_CODEPAGE:// 1253,
case StringEncodingType.CHARSET_WINDOWS_1255_CODEPAGE:// 1255,
case StringEncodingType.CHARSET_ISO_2022_JP_CODEPAGE:// 50220,
case StringEncodingType.CHARSET_ISO_2022_CN_CODEPAGE:// 50227,
case StringEncodingType.CHARSET_ISO_2022_KR_CODEPAGE:// 50225,
case StringEncodingType.CHARSET_ISO_8859_5_CODEPAGE:// 28595,
case StringEncodingType.CHARSET_ISO_8859_7_CODEPAGE:// 28597,
case StringEncodingType.CHARSET_ISO_8859_8_CODEPAGE:// 28598,
case StringEncodingType.CHARSET_BIG5_CODEPAGE:// 950,
case StringEncodingType.CHARSET_GB18030_CODEPAGE:// 54936,
case StringEncodingType.CHARSET_EUC_JP_CODEPAGE:// 20932,
case StringEncodingType.CHARSET_EUC_KR_CODEPAGE:// 51949,
case StringEncodingType.CHARSET_SHIFT_JIS_CODEPAGE:// 932,
case StringEncodingType.CHARSET_IBM855_CODEPAGE:// 855,
case StringEncodingType.CHARSET_IBM866_CODEPAGE:// 866,
case StringEncodingType.CHARSET_KOI8_R_CODEPAGE:// 20866,
case StringEncodingType.CHARSET_MACCYRILLIC_CODEPAGE:// 10007,
case StringEncodingType.CHARSET_HZ_GB_2312_CODEPAGE:// 52936,
//case StringEncodingType.CHARSET_X_ISO_10646_UCS_4_3412_CODEPAGE:// 12000, same as CHARSET_UTF_32LE_CODEPAGE
//case StringEncodingType.CHARSET_X_ISO_10646_UCS_4_2143_CODEPAGE:// 12000, same as CHARSET_UTF_32LE_CODEPAGE
case StringEncodingType.CHARSET_WINDOWS_874_CODEPAGE:// 874
return Encoding.GetEncoding((int)type);
default:
throw new System.NotSupportedException("Error Missing String Encoding Type:" + type.ToString());
}
}
public enum StringEncodingType // the numbers are the codepage
{
Unknown = -1,
ASCII = 20127,
Unicode = 1200,
UTF8 = 65001,
//CHARSET_UTF_16LE_CODEPAGE = 1200, same as unicode
CHARSET_UTF_16BE_CODEPAGE = 1201,
CHARSET_UTF_32LE_CODEPAGE = 12000,
CHARSET_UTF_32BE_CODEPAGE = 12001,
CHARSET_WINDOWS_1251_CODEPAGE = 1251,
CHARSET_WINDOWS_1252_CODEPAGE = 1252,
CHARSET_WINDOWS_1253_CODEPAGE = 1253,
CHARSET_WINDOWS_1255_CODEPAGE = 1255,
CHARSET_ISO_2022_JP_CODEPAGE = 50220,
CHARSET_ISO_2022_CN_CODEPAGE = 50227,
CHARSET_ISO_2022_KR_CODEPAGE = 50225,
CHARSET_ISO_8859_5_CODEPAGE = 28595,
CHARSET_ISO_8859_7_CODEPAGE = 28597,
CHARSET_ISO_8859_8_CODEPAGE = 28598,
CHARSET_BIG5_CODEPAGE = 950,
CHARSET_GB18030_CODEPAGE = 54936,
CHARSET_EUC_JP_CODEPAGE = 20932,
CHARSET_EUC_KR_CODEPAGE = 51949,
CHARSET_SHIFT_JIS_CODEPAGE = 932,
CHARSET_IBM855_CODEPAGE = 855,
CHARSET_IBM866_CODEPAGE = 866,
CHARSET_KOI8_R_CODEPAGE = 20866,
CHARSET_MACCYRILLIC_CODEPAGE = 10007,
CHARSET_HZ_GB_2312_CODEPAGE = 52936,
//CHARSET_X_ISO_10646_UCS_4_3412_CODEPAGE = 12000, same as CHARSET_UTF_32LE_CODEPAGE
//CHARSET_X_ISO_10646_UCS_4_2143_CODEPAGE = 12000, same as CHARSET_UTF_32LE_CODEPAGE
CHARSET_WINDOWS_874_CODEPAGE = 874
}
After banging my head on it for hours, I am at my wits end. I have a hex string in a file that is "68 39 30 00 00". The "39 30" is the decimal value "12345" which I am wanting to replace, and the "68" and "00 00" are just to ensure there is a single match.
I want to pass in a new decimal value such as "12346", and replace the existing value in the file. I have tried converting everything back and fourth between hex, byte arrays, and so on and feel it has to be much simpler than I am making it out to be.
static void Main(string[] args)
{
// Original Byte string to find and Replace "12345"
byte[] original = new byte[] { 68, 39, 30, 00, 00 };
int newPort = Convert.ToInt32("12346");
string hexValue = newPort.ToString("X2");
byte[] byteValue = StringToByteArray(hexValue);
// Build Byte Array of the port to replace with. Starts with /x68 and ends with /x00/x00
byte[] preByte = new byte[] { byte.Parse("68", System.Globalization.NumberStyles.HexNumber) };
byte[] portByte = byteValue;
byte[] endByte = new byte[] { byte.Parse("00", System.Globalization.NumberStyles.HexNumber), byte.Parse("00", System.Globalization.NumberStyles.HexNumber) };
byte[] replace = new byte[preByte.Length + portByte.Length + endByte.Length];
preByte.CopyTo(replace, 0);
portByte.CopyTo(replace, preByte.Length);
endByte.CopyTo(replace, (preByte.Length + portByte.Length));
Patch("Server.exe", "Server1.exe", original, replace);
}
static private byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
The decimal value of 39 30 is 14640 so it will check for the 14640 which is not present.
Hex value for 12345 is 30 39. Just correct the values and your program will work fine.