Reading byte array and converting into float in C# - c#

I know there are many questions related to it but still they are not solving my problem. Below is my byte array:
As you can see that the byte is of 28 and each 4-byte value represents a single value i.e. I have a client machine which sent me 2.4 and while reading it, it is then converted into bytes.
//serial port settings and opening it
var serialPort = new SerialPort("COM2", 9600, Parity.Even, 8, StopBits.One);
serialPort.Open();
var stream = new SerialStream(serialPort);
stream.ReadTimeout = 2000;
// send request and waiting for response
// the request needs: slaveId, dataAddress, registerCount
var responseBytes = stream.RequestFunc3(slaveId, dataAddress, registerCount);
// extract the content part (the most important in the response)
var data = responseBytes.ToResponseFunc3().Data;
What I want to do?
Convert each 4 byte one by one to hex, save them In a separate variable. Like
hex 1 = byte[0], hex2 = byte[1], hex3 = byte[2], hex4 = byte[3]
..... hex28 = byte[27]
Combine 4-byte hex value and then convert them into float and assign them a variable to hold floating value. Like
v1 = Tofloat(hex1,hex2,hex3,hex4); // assuming ToFloat() is a function.
How can I achieve it?

Since you mentioned that the first value is 2.4 and each float is represented by 4 bytes;
byte[] data = { 64, 25, 153, 154, 66, 157, 20, 123, 66, 221, 174, 20, 65, 204, 0, 0, 65, 163, 51, 51, 66, 95, 51, 51, 69, 10, 232, 0 };
We can group the bytes into 4 byte blocks and reverse them and convert each part to float like:
int offset = 0;
float[] dataFloats =
data.GroupBy(x => offset++ / 4) // group by 4. 0/4 = 0, 1/4 = 0, 2/4 = 0, 3/4 = 0 and 4/4 = 1 etc.
// Need to reverse the bytes to make them evaluate to 2.4
.Select(x => BitConverter.ToSingle(x.ToArray().Reverse().ToArray(), 0))
.ToArray();
Now you have an array of 7 floats:

Related

Find byte array inside another byte array and extract x amount of bytes

Any idea how I can find a byte array inside a byte array?
Example
byte[] array1 = { 101, 21, 92, 1, 92, 0, 132, 0, 22 }
byte[] search = { 21, 92 }
so use array search and find it inside array1 then extract x amount of bytes
after the search array up until specific bytes are reached such as,
0, 132, 0, 22
Extraction for example would be in this scenario
1, 92
from array1
byte[] array1 = { 101, 21, 92, 1, 92, 0, 132, 21, 0, 22 };
byte[] search = { 21, 92 };
var data = search.Where(a => array1.Contains(a)).ToList();
foreach (var item in data)
{
Console.WriteLine(item);
}

How to revert array to orginal form after conditional permute

My code:
var unpermuted = new byte[]{137, 208, 135, 4, 191, 255, 132, 99, 85, 54, 58, 137, 208, 37, 151, 30};
var longKey = new byte[] {75, 79, 84, 69, 197, 129, 75, 65, 74, 65, 75, 75, 79, 84, 69, 197, 129, 75, 65, 74, 65};
var permuted = (byte[])unpermuted.Clone();
for(var i = 0; i < permuted.Length;i++)
{
if (i > 1 && (permuted[i] < longKey[i]))
{
var swapCont = permuted[i - 1];
permuted[i - 1] = permuted[i];
permuted[i] = swapCont;
}
}
printArr(unpermuted);
Console.WriteLine();
printArr(permuted);
// How do I reverse permuted array to unpermuted?
Console.WriteLine();
printArr(permuted);
}
public static void printArr(byte[] arr)
{
for(var i = 0; i < arr.Length;i++)
{
Console.Write(arr[i]);
Console.Write(" ");
}
}
I have unpermute array, make deep copy, and after this, if keyValue is higher than value, I swap with previous element.
And the question is:
How to revert permuted array to unpermuted form having only LongKey Array and Permuted array?
It's not possible to "unpermute" the array, given the information that you have.
Imagine that you have the following:
longkey = [1,2,3,9,5]
array = [3,4,9,5,6]
Running your code, the result will be [3,4,5,9,6].
But if the original array is [3,4,5,9,6], the result is the same.
As you can see, there are multiple permutations of the original array that give the same output. And there's not enough information in the result and the longkey array to tell you what the original array was.
In general, if you have a 3-item sequence anywhere in which the following is true, then it's not possible to reliably reverse the operation.
longkey = [b, c, d]
array = [x, y, z]
Where:
b <= x, b <= y
c < x, c > y
d <= z
For example:
longkey = [...,3,9,5,...]
array = [...,9,5,6,...]
The key here is that the 9 can never swap with the thing to its left, and the 6 will never swap with the 5. So the 5 and 9 cannot move except to swap places with each other. If the original order is [9,5,6], the final order will be [5,9,6]. And if the original order is [5,9,6], the result is, again, [5,9,6].

Error splitting an array into two

So I need to cut off the first 16 bytes from my byte array. I followed another post I saw on Stack Overflow to use the following code:
//split message into iv and encrypted bytes
byte[] iv = new byte[16];
byte[] workingHash = new byte[rage.Length - 16];
//put first 16 bytes into iv
for (int i = 0; i < 16; i++)
{
iv[i] = rage[i];
}
Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length);
What we are trying here is to cut off the first 16 bytes from the byte[] rage and put the rest into byte[] workingHash
The error occurs at Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length);
Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
Any help will be much appreciated.
The problem is trivial: Buffer.BlockCopy's last argument requires the correct number of bytes to be copied, which (taking the starting index into account) may not exceed the array's bounds (docs).
Hence the code should look like this, avoiding any for cycles:
Buffer.BlockCopy(rage, 0, iv, 0, 16);
Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length - 16);
Notice the “- 16” at the second line, fixing the original code. The first line replaces the for cycle for the sake of consistency.
Lets assume rage is a byte array of length 20:
var rage = new byte[20]
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
};
After byte[] iv = new byte[16];, iv will contain:
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
After byte[] workingHash = new byte[rage.Length - 16];, workingHash will contain:
{ 0, 0, 0, 0 }
After the for loop iv is:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
You need:
Buffer.BlockCopy(rage, 16, workingHash, 0, rage.Length - 16);
Copy rage.Length - 16 (4) elements from rage's 16th element (which is 17) to workingHash starting from the 0th element.
The result:
{ 17, 18, 19, 20 }
By the way there is a very readable way, probably not as fast as copying arrays, but worth mentioning:
var firstSixteenElements = rage.Take(16).ToArray();
var remainingElements = rage.Skip(16).ToArray();
Fixed:
//split message into iv and encrypted bytes
byte[] iv = new byte[16];
byte[] workingHash = new byte[rage.Length - 16];
//put first 16 bytes into iv
for (int i = 0; i < 16; i++)
{
iv[i] = rage[i];
}
for (int i = 0; i < rage.Length - 16; i++)
{
workingHash[i] = rage[i + 16];
}

Combine one Byte[] to Single Array

i do have an byte array included a range of numbers...
t Block and not the rest!
How can i have all block 4-8 in Temp[] ??
Elements 4-8 (or in reality index 3-7) is 5 bytes. Not 4.
You have the source offset and count mixed up:
Buffer.BlockCopy(bResponse, 3, temp, 0, 5);
Now temp will contain [23232].
If you want the last 4 bytes then use this:
Buffer.BlockCopy(bResponse, 4, temp, 0, 4);
Now temp will contain [3232].
To convert this to an int:
if (BitConverter.IsLittleEndian)
Array.Reverse(temp);
int i = BitConverter.ToInt32(temp, 0);
Edit: (After your comment that [43323232] actually is {43, 32, 32, 32})
var firstByte = temp[0]; // This is 43
var secondByte = temp[1]; // This is 32
var thirdByte = temp[2]; // 32
var fourthByte = temp[3]; // 32
If you want to convert this to an int then the BitConverter example above still works.

Problems converting ADPCM to PCM in XNA

I'm looking to convert ADPCM data into PCM data from an XNA's .xnb file. (So many abbreviations!)
I've used a couple of places for references, including:
http://www.wooji-juice.com/blog/iphone-openal-ima4-adpcm.html
http://www.cs.columbia.edu/~hgs/audio/dvi/p34.jpg and a couple of others.
I believe that I'm close, as I'm getting a sound that's somewhat similar, but there's a lot of static/corruption in the output sound and I can't seem to figure out why.
The conversion comes down to two functions.
private static byte[] convert(byte[] data)
{
byte[] convertedData = new byte[(data.Length) * 4];
stepSize = 7;
newSample = 0;
index = 0;
var writeCounter = 0;
for (var x = 4; x < data.Length; x++)
{
// First 4 bytes of a block contain initialization information
if ((x % blockSize) < 4)
{
if (x % blockSize == 0) // New block
{
// set predictor/NewSample and index from
// the preamble of the block.
newSample = (short)(data[x + 1] | data[x]);
index = data[x + 2];
}
continue;
}
// Get the first 4 bits from the byte array,
var convertedSample = calculateNewSample((byte)(data[x] >> 4)); // convert 4 bit ADPCM sample to 16 bit PCM sample
// Store 16 bit PCM sample into output byte array
convertedData[writeCounter++] = (byte)convertedSample >> 8;
convertedData[writeCounter++] = (byte)convertedSample & 0x0ff;;
// Convert the next 4 bits of the 8 bit array.
convertedSample = calculateNewSample((byte)(data[x] & 0x0f)); // convert 4 bit ADPCM sample to 16 bit PCM sample.
// Store 16 bit PCM sample into output byte array
convertedData[writeCounter++] = (byte)(convertedSample >> 8);
convertedData[writeCounter++] = (byte)(convertedSample & 0x0ff);
}
// Conversion complete, return data
return convertedData;
}
private static short calculateNewSample(byte sample)
{
Debug.Assert(sample < 16, "Bad sample!");
var indexTable = new int[16] { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 };
var stepSizeTable = new int[89] { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};
var sign = sample & 8;
var delta = sample & 7;
var difference = stepSize >> 3;
// originalsample + 0.5 * stepSize / 4 + stepSize / 8 optimization.
//http://www.cs.columbia.edu/~hgs/audio/dvi/p34.jpg
if ((delta & 4) != 0)
difference += stepSize;
if ((delta & 2) != 0)
difference += stepSize >> 1;
if ((delta & 1) != 0)
difference += stepSize >> 2;
if (sign != 0)
newSample -= (short)difference;
else
newSample += (short)difference;
// Increment index
index += indexTable[sample];
index = (int)MathHelper.Clamp(index, 0, 88);
newSample = (short)MathHelper.Clamp(newSample, -32768, 32767); // clamp between appropriate ranges
// compute new stepSize.
stepSize = stepSizeTable[index];
return newSample;
}
I don't believe the actual calculateNewSample() function is incorrect, as I've passed it the input values from http://www.cs.columbia.edu/~hgs/audio/dvi/p35.jpg and recieved the same output they have. I've tried flipping between the high/low order bytes to see if I've got that backwards to no avail as well. I feel like there's possibly something fundamental that I'm missing out on, but am having trouble finding it.
Any help would be seriously appreciated.

Categories