I work on a small project and i need to store 4 int types in a byte array(which will be sent later on a socket).
This is the code:
int a = 566;
int b = 1106;
int c = 649;
int d = 299;
byte[] bytes = new byte[16];
bytes[0] = (byte)(a >> 24);
bytes[1] = (byte)(a >> 16);
bytes[2] = (byte)(a >> 8);
bytes[3] = (byte)a;
I shifted the bits of the first value,but i'm not sure now how to retrieve it back...doing the reversed process.
I hope my question is clear,if i missed somthing i'll be glad to explain it again.
Thanks.
To extract the Int32 back out from the byte array, use this expression:
int b = bytes[0] << 24
| bytes[1] << 16
| bytes[2] << 8
| bytes[3]; // << 0
Here is a .NET Fiddle that demonstrates.
Depends on you comment reply, you can do it like this:
int a = 10;
byte[] aByte = BitConverter.GetBytes(a);
int b = 20;
byte[] bByte = BitConverter.GetBytes(b);
List<byte> listOfBytes = new List<byte>(aByte);
listOfBytes.AddRange(bByte);
byte[] newByte = listOfBytes.ToArray();
You can use a MemoryStream to wrap an array of bytes, and then use BinaryWriter to write items to the array, and BinaryReader to read items from the array.
Sample code:
int a = 566;
int b = 1106;
int c = 649;
int d = 299;
// Writing.
byte[] data = new byte[sizeof(int) * 4];
using (MemoryStream stream = new MemoryStream(data))
using (BinaryWriter writer = new BinaryWriter(stream))
{
writer.Write(a);
writer.Write(b);
writer.Write(c);
writer.Write(d);
}
// Reading.
using (MemoryStream stream = new MemoryStream(data))
using (BinaryReader reader = new BinaryReader(stream))
{
a = reader.ReadInt32();
b = reader.ReadInt32();
c = reader.ReadInt32();
d = reader.ReadInt32();
}
// Check results.
Trace.Assert(a == 566);
Trace.Assert(b == 1106);
Trace.Assert(c == 649);
Trace.Assert(d == 299);
Related
So i have this file that i am opening:
static void Encrypt(string fileName)
{
using (FileStream stream = File.OpenRead(fileName))
{
using (BinaryReader reader = new BinaryReader(stream))
{
for (int i = 0; i < stream.Length; i++)
{
byte b = reader.ReadByte();
byte newByte = (byte(b + 5))
}
}
}
}
And i want to add specific value to each byte in my file and save it.
So just store the new bytes in a collection and save them after reading whole file.
var newBytes = new List<byte>();
...
for (int i = 0; i < stream.Length; i++)
{
byte b = reader.ReadByte();
newBytes.Add(b + 5);
}
...
File.WriteAllBytes(filePath, newBytes.ToArray());
You could do something like this:
byte b = reader.ReadByte();
int newNumber = (int)b + 5;
byte newByte = (byte)(newNumber % 256);
To have control over the overflow you may create, I suggest you change from byte to int.
Then this adds 5 to the byte value you read, wrapping to zero when you reach b == 251, as 251 + 5 == 256 and 256 % 256 == 0.
I need to perform FFT and I have a sound sample .wav format.
The function needs double[] xRe, double[] xIm, REAL PART and imaginary part How to convert the sound file into double[]?
I have never seen something like that. Could not find in the internet that kind of operation.
This is this sound sample:
http://www.speedyshare.com/fFD8t/e.wav
Please help, cause I used Pascal and now don't know what to do here.
It's a simple stream operation.
You have to read wav file header.
You have to read data bytes.
Paste from MSDN:
BinaryReader reader = new BinaryReader(waveFileStream);
//Read the wave file header from the buffer.
int chunkID = reader.ReadInt32();
int fileSize = reader.ReadInt32();
int riffType = reader.ReadInt32();
int fmtID = reader.ReadInt32();
int fmtSize = reader.ReadInt32();
int fmtCode = reader.ReadInt16();
int channels = reader.ReadInt16();
int sampleRate = reader.ReadInt32();
int fmtAvgBPS = reader.ReadInt32();
int fmtBlockAlign = reader.ReadInt16();
int bitDepth = reader.ReadInt16();
if (fmtSize == 18)
{
// Read any extra values
int fmtExtraSize = reader.ReadInt16();
reader.ReadBytes(fmtExtraSize);
}
int dataID = reader.ReadInt32();
int dataSize = reader.ReadInt32();
// Store the audio data of the wave file to a byte array.
byteArray = reader.ReadBytes(dataSize);
// After this you have to split that byte array for each channel (Left,Right)
// Wav supports many channels, so you have to read channel from header
Here this is more detailed explanation:
http://msdn.microsoft.com/en-us/library/ff827591.aspx
And here you can read about WAV file format:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
And something about WAV as complex numbers and FFT:
How to convert wave data into Complex numbers
Kamil's solution was very close, but didn't work for some of the wav files I ran across. After some research, here is what I discovered. In the description of the canonical WAV PCM sound file format (http://soundfile.sapp.org/doc/WaveFormat/), I discovered this reference in the Notes: There may be additional subchunks in a Wave data stream. If so, each will have a char[4] SubChunkID, and unsigned long SubChunkSize, and SubChunkSize amount of data.
In a few wav files I ran across, there were indeed extra subchunks, so I had to add some code to read until it found the "data" marker. After adding this, it worked universally. My complete code is below.
public static bool ReadWavFile(string filename, out float[] L, out float[] R)
{
L = R = null;
try
{
using (FileStream fs = File.Open(filename, FileMode.Open))
{
BinaryReader reader = new BinaryReader(fs);
// chunk 0
int chunkID = reader.ReadInt32();
int fileSize = reader.ReadInt32();
int riffType = reader.ReadInt32();
// chunk 1
int fmtID = reader.ReadInt32();
int fmtSize = reader.ReadInt32(); // bytes for this chunk
int fmtCode = reader.ReadInt16();
int channels = reader.ReadInt16();
int sampleRate = reader.ReadInt32();
int byteRate = reader.ReadInt32();
int fmtBlockAlign = reader.ReadInt16();
int bitDepth = reader.ReadInt16();
if (fmtSize == 18)
{
// Read any extra values
int fmtExtraSize = reader.ReadInt16();
reader.ReadBytes(fmtExtraSize);
}
// chunk 2 -- HERE'S THE NEW STUFF (ignore these subchunks, I don't know what they are!)
int bytes;
while(new string(reader.ReadChars(4)) != "data")
{
bytes = reader.ReadInt32();
reader.ReadBytes(bytes);
}
// DATA!
bytes = reader.ReadInt32();
byte[] byteArray = reader.ReadBytes(bytes);
int bytesForSamp = bitDepth / 8;
int samps = bytes / bytesForSamp;
float[] asFloat = null;
switch (bitDepth)
{
case 64:
double[]
asDouble = new double[samps];
Buffer.BlockCopy(byteArray, 0, asDouble, 0, bytes);
asFloat = Array.ConvertAll(asDouble, e => (float)e);
break;
case 32:
asFloat = new float[samps];
Buffer.BlockCopy(byteArray, 0, asFloat, 0, bytes);
break;
case 16:
Int16[]
asInt16 = new Int16[samps];
Buffer.BlockCopy(byteArray, 0, asInt16, 0, bytes);
asFloat = Array.ConvertAll(asInt16, e => e / (float)Int16.MaxValue);
break;
default:
return false;
}
switch (channels)
{
case 1:
L = asFloat;
R = null;
return true;
case 2:
L = new float[samps];
R = new float[samps];
for (int i = 0, s = 0; i < samps; i++)
{
L[i] = asFloat[s++];
R[i] = asFloat[s++];
}
return true;
default:
return false;
}
}
}
catch
{
Debug.WriteLine("...Failed to load note: " + filename);
return false;
//left = new float[ 1 ]{ 0f };
}
}
I have a hexadecimal string (e.g 0CFE9E69271557822FE715A8B3E564BE) and I want to write it to a file as bytes. For example,
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
00000000 0C FE 9E 69 27 15 57 82 2F E7 15 A8 B3 E5 64 BE .þži'.W‚/ç.¨³åd¾
How can I accomplish this using .NET and C#?
If I understand you correctly, this should do the trick. You'll need add using System.IO at the top of your file if you don't already have it.
public bool ByteArrayToFile(string fileName, byte[] byteArray)
{
try
{
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(byteArray, 0, byteArray.Length);
return true;
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in process: {0}", ex);
return false;
}
}
The simplest way would be to convert your hexadecimal string to a byte array and use the File.WriteAllBytes method.
Using the StringToByteArray() method from this question, you'd do something like this:
string hexString = "0CFE9E69271557822FE715A8B3E564BE";
File.WriteAllBytes("output.dat", StringToByteArray(hexString));
The StringToByteArray method is included below:
public static 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();
}
Try this:
private byte[] Hex2Bin(string hex)
{
if ((hex == null) || (hex.Length < 1)) {
return new byte[0];
}
int num = hex.Length / 2;
byte[] buffer = new byte[num];
num *= 2;
for (int i = 0; i < num; i++) {
int num3 = int.Parse(hex.Substring(i, 2), NumberStyles.HexNumber);
buffer[i / 2] = (byte) num3;
i++;
}
return buffer;
}
private string Bin2Hex(byte[] binary)
{
StringBuilder builder = new StringBuilder();
foreach(byte num in binary) {
if (num > 15) {
builder.AppendFormat("{0:X}", num);
} else {
builder.AppendFormat("0{0:X}", num); /////// 大于 15 就多加个 0
}
}
return builder.ToString();
}
You convert the hex string to a byte array.
public static 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();
}
Credit: Jared Par
And then use WriteAllBytes to write to the file system.
This example reads 6 bytes into a byte array and writes it to another byte array. It does an XOR operation with the bytes so that the result written to the file is the same as the original starting values. The file is always 6 bytes in size, since it writes at position 0.
using System;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
byte[] b1 = { 1, 2, 4, 8, 16, 32 };
byte[] b2 = new byte[6];
byte[] b3 = new byte[6];
byte[] b4 = new byte[6];
FileStream f1;
f1 = new FileStream("test.txt", FileMode.Create, FileAccess.Write);
// write the byte array into a new file
f1.Write(b1, 0, 6);
f1.Close();
// read the byte array
f1 = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
f1.Read(b2, 0, 6);
f1.Close();
// make changes to the byte array
for (int i = 1; i < b2.Length; i++)
{
b2[i] = (byte)(b2[i] ^ (byte)10); //xor 10
}
f1 = new FileStream("test.txt", FileMode.Open, FileAccess.Write);
// write the new byte array into the file
f1.Write(b2, 0, 6);
f1.Close();
f1 = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
// read the byte array
f1.Read(b3, 0, 6);
f1.Close();
// make changes to the byte array
for (int i = 1; i < b3.Length; i++)
{
b4[i] = (byte)(b3[i] ^ (byte)10); //xor 10
}
f1 = new FileStream("test.txt", FileMode.Open, FileAccess.Write);
// b4 will have the same values as b1
f1.Write(b4, 0, 6);
f1.Close();
}
}
}
I'm using BitConverter.ToInt32 to pack 3 byte values into an int, like so:
byte R = 0;
byte G = 0;
byte B = 0;
int i = BitConverter.ToInt32(new byte[] { R, G, B, 0 }, 0);
Is there a faster way to do this that doesn't involve the creation of a new int each time? Getting the bytes out of an int is easy:
int i = 34234;
byte B = (byte)(i >> 0);
byte G = (byte)(i >> 8);
byte R = (byte)(i >> 16);
Is there a simple way to reverse this process and use bit-shifting to write the RGB bytes back over an existing int?
int i = (B << 0) | (G << 8) | (R << 16);
You ought to consider the Color structure. It has R, G and B properties and FromArgb() and ToArgb() methods.
If I want to represent a guid as a set of integers how would I handle the conversion? I'm thinking along the lines of getting the byte array representation of the guid and breaking it up into the fewest possible 32 bit integers that can be converted back into the original guid. Code examples preferred...
Also, what will the length of the resulting integer array be?
As a GUID is just 16 bytes, you can convert it to four integers:
Guid id = Guid.NewGuid();
byte[] bytes = id.ToByteArray();
int[] ints = new int[4];
for (int i = 0; i < 4; i++) {
ints[i] = BitConverter.ToInt32(bytes, i * 4);
}
Converting back is just getting the integers as byte arrays and put together:
byte[] bytes = new byte[16];
for (int i = 0; i < 4; i++) {
Array.Copy(BitConverter.GetBytes(ints[i]), 0, bytes, i * 4, 4);
}
Guid id = new Guid(bytes);
System.Guid guid = System.Guid.NewGuid();
byte[] guidArray = guid.ToByteArray();
// condition
System.Diagnostics.Debug.Assert(guidArray.Length % sizeof(int) == 0);
int[] intArray = new int[guidArray.Length / sizeof(int)];
System.Buffer.BlockCopy(guidArray, 0, intArray, 0, guidArray.Length);
byte[] guidOutArray = new byte[guidArray.Length];
System.Buffer.BlockCopy(intArray, 0, guidOutArray, 0, guidOutArray.Length);
System.Guid guidOut = new System.Guid(guidOutArray);
// check
System.Diagnostics.Debug.Assert(guidOut == guid);
Somehow I had much more fun doing it this way:
byte[] bytes = guid.ToByteArray();
int[] ints = new int[bytes.Length / sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
ints[i / sizeof(int)] = ints[i / sizeof(int)] | (bytes[i] << 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}
and converting back:
byte[] bytesAgain = new byte[ints.Length * sizeof(int)];
for (int i = 0; i < bytes.Length; i++) {
bytesAgain[i] = (byte)((ints[i / sizeof(int)] & (byte.MaxValue << 8 * ((sizeof(int) - 1) - (i % sizeof(int))))) >> 8 * ((sizeof(int) - 1) - (i % sizeof(int))));
}
Guid guid2 = new Guid(bytesAgain);
Will the build-in Guid structure not suffice?
Constructor:
public Guid(
byte[] b
)
And
public byte[] ToByteArray()
Which, returns a 16-element byte array that contains the value of this instance.
Packing the bytes into integers and visa versa should be trivial.
A Guid is typically just a 128-bit number.
-- Edit
So in C#, you can get the 16 bytes via
byte[] b = Guid.NewGuid().ToByteArray();