C#, How to split a byte array by delimiter? - c#

I have a byte array that contains a collection of 2 byte hexadecimal numbers separated by ','. How could it be split by ',' and then the numbers be converted to integers?
The byte array contains values in ascii format.
edit:
Example
My valid character range is 0 to 9 ,A to F and comma
so my stream should look like
70, 67, 65, 57, 44, 55, 68, 66, 53, 44....
this would be equivalent to hexadecimal
FCA9 and 7DB5

If your byte array is truly ASCII encoded (ONE byte per character), then the following would work:
int[] ints = Encoding.ASCII.GetString(asciiEncodedBytes).Split(',')
.Select(x => Convert.ToInt32(x,16)).ToArray();
This will handle mixed case and variable length hex numbers, too.

I would convert the byte array to string and then use String.Split(',')

This should work, though my C# is a bit rusty...
byte[] input = { 1, 0, 0, 0, ',', 10, 15, ',', 100, 0, 0, 0, ',' };
List<int> output = new List<int>();
int lastIndex = 0;
for (int i = 0; i < input.Length; i ++) {
if (input[i] == ',')
{
if (i - lastIndex == 4)
{
byte[] tmp = { input[i - 4], input[i - 3], input[i - 2], input[i - 1] };
output.Add(BitConverter.ToInt32(tmp, 0));
}
lastIndex = i + 1;
}
}

Related

How do I copy the array elements and also reversing certain elements with Array.Copy() in c#?

Elements of SourceArray are being copied to 2 separate Arrays namely DestArray1 and DestArray2.
output:
DestArray1 will have the first 4 elements of SourceArray but in the reverse form [4 3 2 1]
DestArray2 will have the last 4 elements of SourceArray. [5 6 7 8]
I want to replace the for loop with Array.Copy() method
if not reversed then Array.Copy() works kind of fine except for the last element, but to copy with reverse, it seems the Array.Copy doesn't work or I am not able to implement it.
int i, j;
int bytelength =8;
int halfbytelength = 4;
byte[] SourceArray = new byte[]{ 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] DestArray1 = new byte[4];
byte[] DestArray2 = new byte[4];
for (i = halfbytelength - 1, j = 0; i >= 0; i -= 1, j++)
{
DestArray1[j] = SourceArray[i];
}
for (i = halfbytelength; i < bytelength; i += 1)
{
DestArray2[i - halfbytelength] = SourceArray[i];
}
I tried following the code but the results are not as expected as seen in(Results:), is there a way to do it?
Array.Copy(SourceArray, 0, DestArray1, 3, 0);
Array.Copy(SourceArray, 4, DestArray2, 0, 3);
Result:
DestArray1: [0 0 0 0]
DestArray2: [5 6 7 0]
First array.
To reverse array you can just call Array.Reverse() after copying:
Array.Copy(SourceArray, 0, DestArray1, 0, 4);
Array.Reverse(DestArray1);
Second array.
if not reversed then Array.Copy() works kind of fine except for the
last element
Because you pass invalid count of elements to copy (last parameter):
Array.Copy(SourceArray, 4, DestArray2, 0, 3); // 3 - elements count, not an index
Simply replace 3 with 4:
Array.Copy(SourceArray, 4, DestArray2, 0, 4); // 4 and it will copy including the last element

How to convert an integer to binary stored in array

I know how to convert an integer from decimal to fixed length binary string:
int number = 3;
int toBase = 2;
int length = 8;
Convert.ToString(number, toBase).PadLeft(length, '0')
Output:
00000011
How to assign the individual elements of that binary string to either int (or bool) array, such that after the conversion the array will look like1:
int[] binary = {0, 0, 0, 0, 0, 0, 1, 1}
or
bool[] binary = {false, false, false, false, false, false, true, true};
1. Using the facilities and not trivial for loop with char to int (or bool) type conversions.
You can add some Linq to represent the string as an array:
string source = Convert.ToString(number, toBase).PadLeft(length, '0');
...
int[] binary = source.Select(c => c - '0').ToArray();
...
bool[] binary = source.Select(c => c == '1').ToArray();
Or you can compute arrays directly:
int[] binary = Enumerable
.Range(1, length)
.Select(i => number / (1 << (length - i)) % 2)
.ToArray();
bool[] binary = Enumerable
.Range(1, length)
.Select(i => number / (1 << (length - i)) % 2 == 1)
.ToArray();
If you store the string you have created, for example
string theBinaryString = Convert.ToString(number, toBase).PadLeft(length, '0');
int[] binary = new int[8];
for(int i = 0; i < 8; i++)
{
binary[i] = int.parse(theBinaryString[i].ToString());
}
Once the loop has finished you will have the array you are looking for, the ToString() is required as selecting from a string as if it was an array returns a char, which cannot be parsed into an int.
You can do it without converting the number to binary string:
var num = 123;
var bits = Enumerable.Range(0, 8).Select(i => (num >> (7-i)) & 1).ToArray();
The idea is to shift the number right sequentially by a decreasing number of positions, and mask off all bits except least significant one.
Demo.
maybe like this;
"1000110101110".ToCharArray().Select(c => c - '0').ToArray()
will give you:
int[13] { 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0 }
int[] intArray = stringNumber.ToCharArray().Select(n => Convert.ToInt32(n)).ToArray();

Get char array from byte array and then back to byte array

I don't know why but when you do the next thing you will never get the same as the original byte array:
var b = new byte[] {252, 2, 56, 8, 9};
var g = System.Text.Encoding.ASCII.GetChars(b);
var f = System.Text.Encoding.ASCII.GetBytes(g);
If you will run this code you will see that b != f, Why?!
Is there any way to convert bytes to chars and then back to bytes and get the same as the original byte array?
byte value can be 0 to 255.
When the byte value > 127, then result of
System.Text.Encoding.ASCII.GetChars()
is always '?' which has value 63
Therefore,
System.Text.Encoding.ASCII.GetBytes()
result always get 63 (wrong value) for those have initial byte value > 127
If you need TABLE ASCII -II then you can do as following
var b = new byte[] { 252, 2, 56, 8, 9 };
//another encoding
var e = Encoding.GetEncoding("437");
//252 inside the mentioned table is ⁿ and now you have it
var g = e.GetString(b);
//now you can get the byte value 252
var f = e.GetBytes(g);
Similar posts you can read
How to convert the byte 255 to a signed char in C#
How can I convert extended ascii to a System.String?
Why not use chars?
var b = new byte[] {252, 2, 56, 8, 9};
var g = new char[b.Length];
var f = new byte[g.Length]; // can also be b.Length, doens't really matter
for (int i = 0; i < b.Length; i++)
{
g[i] = Convert.ToChar(b[i]);
}
for (int i = 0; i < f.Length; i++)
{
f[i] = Convert.ToByte(g[i]);
}
The only difference is first byte: 252. Because ascii char is 1-byte signed char and it's value range is -128 to 127. Actually your input is incorrect. signed char can't be 252.

Re sizing array [duplicate]

This question already has answers here:
Deleting A Specified Element In An Array Using Random Class
(4 answers)
Closed 9 years ago.
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, Token);
Array.Copy(arrTmp, r+1, numbers, Token, oldLength - Token - 1);
This all i got to remove a specified element from a value type array but it doesn't work.
I got 4 elements of value type array. I have stored 4 different numbers in it.
array[0] = 2;
array[1] = 4;
array[2] = 6;
array[3] = 8;
i got a random class to randomly pick a number if it is 2 has to be removed from my array in an ascending sequential order each element should be inspected and eliminated.
You would do much easier using the List class
List<int> l = new List<int>();
l.Add(2);
l.Add(4);
...
l.Remove(2);
int oldLength = numbers.Length;
int[] arrTmp = new int[oldLength - 1];
for(int i = 0, j = 0; i < oldLength || j < arrTmp.Length; i++)
{
if(numbers[i] == Token)
continue;
arrTmp[j++] = numbers[i];
}
using linq:
var newArray = numbers.Where(n=> n!= Token).ToArray();
This would be the general approach:
int oldLength = numbers.Length;
int[] arrTmp = numbers;
numbers = new int[oldLength - 1];
Array.Copy(arrTmp, numbers, r);
Array.Copy(arrTmp, r + 1, numbers, r, oldLength - r - 1);
Note the use of r everywhere. Here r would be the index of the element to omit.
If you really need to use plain arrays and copy their contents using Array.Copy (which is not a common way of handling things in .NET), then start by using a pen and write down correct indices and lengths of the array parts you are trying to copy.
Starting to code the solution before you know how to solve it won't get you far.
So, start with an example array and a random index:
// starting array
int[] array = { 0, 1, 2, 3, 4, 5, 6, 7 };
// index to remove
int indexToRemove = new Random().Next(array.Length);
Now, presume that indexToRemove is 3 and try to do it by hand:
Part 1: { 0, 1, 2 } (start = 0, length = 3)
Part 2: { 4, 5, 6, 7 } (start = 4, length = 4)
From this concrete example, you can try to infer the general formula for offset and length of these two array parts:
Part 1: start = 0, length = (indexToRemove - 1)
Part 2: start = (indexToRemove + 1), length = (array.Length - indexToRemove - 1)
The code itself is then trivial:
var len = array.Length;
var newArray = new int[len - 1];
Array.Copy(array, 0, newArray, 0, indexToRemove - 1);
Array.Copy(array, indexToRemove + 1, newArray, indexToRemove, len - indexToRemove - 1);
Additionally, the Array.Copy can be used to copy a part of an array over itself, which means you can just move the second part of the array back by one position, and then resize the initial array using Array.Resize:
// do not create a new array, but simply "move" the 2nd part to left
Array.Copy(array, indexToRemove + 1, array, indexToRemove, len - indexToRemove - 1);
// finally, resize the original array
Array.Resize(ref array, array.Length - 1);
Of course, if you simply used a List<int>, then you would simply use the List<T>.RemoveAt method to remove the item:
var list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int indexToRemove = new Random().Next(list.Count);
list.RemoveAt(indexToRemove);

How to read a range of bytes from a bytearray in c#

I have to read a range of bytes from a byte array. I have the starting position and the ending position to read.
-(NSData *) getSubDataFrom:(int)stPos To:(int)endPos withData:(NSData *) data{
NSRange range = NSMakeRange(stPos, endPos);
return [data subDataWithRage:range];
}
The above code in ObjectiveC reads the range of data(bytes) from a NSData(byteArray). Is there any equivelent method in c# to do the same. or how else we can do this. Please advise!
What do you mean by read? Copy a range of bytes into another byte array?
var mainArray = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
var startPos = 5;
var endPos = 10;
var subset = new byte[endPos - startPos + 1];
Array.Copy(mainArray, startPos, subset, 0, endPos - startPos + 1);
From MSDN
Try the Array.Copy() or Array.CopyTo() method.

Categories

Resources