What's wrong with this 2-bytes-to-int conversion? - c#

I'm trying to parse a JPEG file. This page says that the format is the following :
0xFF+Marker Number(1 byte)+Data size(2 bytes)+Data(n bytes)
So, when I encounter a 0xFF, I read the data like this (s is the JPEG file stream) :
int marker, size;
byte[] data;
//marker number (1 byte)
marker = s.ReadByte();
//size (2 bytes)
byte[] b = new byte[2];
s.Read(b, 0, 2);
size = BitConverter.ToInt16(b, 0);
Problem is, size's value after that is -7937 (which causes the next lines to raise an exception because I try to allow a -7937-long byte[]). b[0] == 255 and b[1] == 224.
I suspect I don't use BitConverter.ToInt16 properly, but I can't find what I did wrong.
The BitConverter doc page says that "The order of bytes in the array must reflect the endianness of the computer system's architecture", but when I do this :
byte a = b[0]; b[0] = b[1]; b[1] = a;
size = BitConverter.ToInt16(b, 0);
...I get size == -32 which is not really better.
What's the problem ?

Integers are stored in Big Endian order in JPEG. If you are on a little endian system (e.g. Intel) you need to reverse the order of the bytes in the length field. Length fields are unsigned.

The data in question was an unsigned int. Using the uint type and BitConverter.ToUInt16 fixed it.

Related

Converting Byte[] to a Int8

Is there any way to convert a Byte[] into a int8? I have been given a binary file that contains a list of input parameters for a test. The parameters vary in size from uint32 down to uint8. I am having no problem reading in the file, what is tricky is getting the values to display in the GUI.
Here's is the basis of what I'm doing:
private Byte[] blockSize;
private Byte[] binSize;
FileStream filen = File.OpenRead(file);
BinaryReader br = new BinaryReader(filen);
blockSize = br.ReadBytes(4);
binSize = br.ReadBytes(1);
No problems with that considering that the first 32 bits (4 bytes) of the parameter file are the blockSize and the next 8 bits (1 byte) are the value for my binSize variable. Where the problem comes is in displaying it.
textBox1.Text = BitConverter.ToInt32(blockSize, 0).ToString();
textBox2.Text = BitConverter.ToString(binSize, 0).ToString();
Lets say that my binary input file contains the following 5 bytes of data "0A 00 00 00 0A". My first textbox displays '10', my second textbox displays '0A'. I want the hex value converted into the more human understandable decimal value. It seems to work fine as long as the parameter in the input file is greater than 1 byte so I can easily convert it using ToInt16 or ToInt32, but I have nothing for the 8bit variety.
Your problem that r.ReadBytes(1); return byte[] then your call BitConverter.ToString(bytearray) with byte array as parameter which do the next:
Converts the numeric value of each element of a specified array of
bytes to its equivalent hexadecimal string representation
BinaryReader has methods
int ReadInt32()
byte ReadByte()
Change types of blockSize to int and binSize to byte and use those methods
int blockSize = br.ReadInt32();
byte binSize = br.ReadByte();
textBox1.Text = blockSize.ToString();
textBox2.Text = binSize.ToString();
From MSDN:
ReadInt32()
Reads a 4-byte signed integer from the current stream and advances the
current position of the stream by four bytes.
ReadByte()
Reads the next byte from the current stream and advances the current
position of the stream by one byte.

Add PPOOE layer tp packet - convert length into byte

I have application that play Pcap files and i try to add function that wrap my packet with PPPOE layer.
so almost all done except large packets that i didn't understand yet how to set the new langth after add PPPOE layer.
For example this packet:
As you can see this packet length is 972 bytes (03 cc), and all i want is to convert it to decimal, after see this packet byte[] in my code i can see that this value converted into 3 and 204 in my packet byte[], so my question is how this calculation works ?
Those two bytes represents a short (System.Int16) in bigendian notation (most significant byte first).
You can follow two approaches to get the decimal value of those two bytes. One is with the BitConverter class, the other is by doing the calculation your self.
BitConverter
// the bytes
var bytes = new byte[] {3, 204};
// are the bytes little endian?
var littleEndian = false; // no
// What architecure is the BitConverter running on?
if (BitConverter.IsLittleEndian != littleEndian)
{
// reverse the bytes if endianess mismatch
bytes = bytes.Reverse().ToArray();
}
// convert
var value = BitConverter.ToInt16( bytes , 0);
value.Dump(); // or Console.WriteLine(value); --> 972
Calculate your self
base 256 of two bytes:
// the bytes
var bytes2 = new byte[] {3, 204};
// [0] * 256 + [1]
var value2 = bytes2[0] * 256 + bytes2[1]; // 3 * 256 + 204
value2.Dump(); // 972

Best way to convert file containing ASCII representations of bytes to real bytes C# .NET

I have a file containing some data (for example, "00927E2B112DB958......"). This data is a representation of bytes in ASCII form. The bytes are 8 bit, so 2 ASCII chars map to each byte that needs to go into the final output buffer array.
What is the best way to do this?
EDIT: What I am trying to do is go from a string that looks like "00DFFF" to a byte array of {0x00, 0xDF, 0xFF}, for example. I guess this wasn't clear.
Thanks!
private ICollection<byte> HexString2Ascii(string hexString)
{
var bytes = new List<byte>(hexString.Length / 2);
for (int i = 0; i <= hexString.Length - 2; i += 2)
bytes.Add(byte.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
return bytes;
}

How to produce 8 bytes from 4 bytes with a reproducible operation?

I've 4 bytes of data and need an 8 bytes array for a security operation. I should produce these 8 bytes form the 4 bytes byte array and this should be reproducible.
I was thinking of using exact byte array and adding 4 extra bytes and fill them with AND, OR, XOR... of the initial array in a known sequence. I'm not sure if it's a good idea. I just need an 8 byte array from this 4 bytes and the operation should be reproducible (same 8 bytes with same given 4 bytes). Please give an example in C#
Why not just pad the existing 4 bytes with another 4 bytes of zeroes? Or repeat the original 4 bytes. For example:
static byte[] Pad(byte[] input)
{
// Alternatively use Array.Resize
byte[] output = new byte[input.Length + 4];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
return output;
}
static byte[] Repeat(byte[] input)
{
byte[] output = new byte[input.Length * 2];
Buffer.BlockCopy(input, 0, output, 0, input.Length);
Buffer.BlockCopy(input, 0, output, input.Length, input.Length);
return output;
}
Both of these fulfil your original criteria, I believe... but I suspect you're looking for something else. If that's the case, you need to be explicit about what you need.
EDIT: As I've said in the comments, you're basically not adding any real security here - padding will make that clearer, IMO. On the other hand, if you do want some security-through-obscurity, you could find a random number generator that allows seeding, and use that as a starting point. For example:
// Don't use this - see below. Just the concept...
int seed = BitConverter.ToInt32(input, 0); // TODO: Cope with endianness
Random rng = new Random(seed);
byte[] output = new byte[8];
Buffer.BlockCopy(input, 0, output, 0, 4);
for (int i = 4; i < 8; i++) {
output[i] = (byte) rng.Next(256);
}
Now, the reason I've got the comment above is that you probably need an algorithm which is guaranteed not to change between versions of .NET. Find code to something like the Mersenne Twister, for exmaple.
There are multiple methods of doing padding for block ciphers.
This Wikipedia article covers some of the more accepted solutions: http://en.wikipedia.org/wiki/Padding_(cryptography)#Padding_methods
Barring any other considerations, I would use PKCS#7 padding.
How about
bytes.Concat(bytes)
I would be very careful. If a security operation requires 64 bits worth of data it is probably because it requires that much data. If you create your 64 bits from 32 bits with a known reproducible formula you will still only have 32 bits worth of data.
If the security is not affected by the data you have you can just fill the the remaining four bytes with ones or zeros. But you should really try to get 8 bytes of "real" data.

Convert byte array to short array in C#

I'm currently reading a file and wanted to be able to convert the array of bytes obtained from the file into a short array.
How would I go about doing this?
Use Buffer.BlockCopy.
Create the short array at half the size of the byte array, and copy the byte data in:
short[] sdata = new short[(int)Math.Ceiling(data.Length / 2)];
Buffer.BlockCopy(data, 0, sdata, 0, data.Length);
It is the fastest method by far.
One possibility is using Enumerable.Select:
byte[] bytes;
var shorts = bytes.Select(b => (short)b).ToArray();
Another is to use Array.ConvertAll:
byte[] bytes;
var shorts = Array.ConvertAll(bytes, b => (short)b);
A shorthard is a compound of two bytes. If you are writing all the shorts to the file as true shorts then those conversions are wrong. You must use two bytes to get the true short value, using something like:
short s = (short)(bytes[0] | (bytes[1] << 8))
short value = BitConverter.ToInt16(bytes, index);
I dont know, but I would have expected another aproach to this question.
When converting a sequence of bytes into a sequence of shorts, i would have it done like #Peter did
short s = (short)(bytes[0] | (bytes[1] << 8))
or
short s = (short)((bytes[0] << 8) | bytes[1])
depending on endianess of the bytes in the file.
But the OP didnt mention his usage of the shorts or the definition of the shorts in the file.
In his case it would make no sense to convert the byte array to a short array, because it would take twice as much memory, and i doubt if a byte would be needed to be converted to a short when used elsewhere.
short[] wordArray = Array.ConvertAll(byteArray, (b) => (short)b);
byte[] bytes;
var shorts = bytes.Select(n => System.Convert.ToInt16(n)).ToArray();

Categories