469,891 Members | 2,173 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,891 developers. It's quick & easy.

Method to Unpack byte array into a UInt64

Hi Group

I am trying to write a method to unpack a byte array into an Uint64.
But the results are wrong.

public static void UnpackUint64(ref UInt64 dst, byte[] Data,
ref uint Index)
{
dst = Data[Index++];
dst += (UInt64)((Data[Index++] & 0xffffffff) << 08);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 16);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 24);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 32);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 40);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 48);
dst += (UInt64)((Data[Index++] & 0xffffffff) << 56);
}

The method I use to pack the Uint64 into the byte array is

public static void PackUint64(ulong src, byte[] Data, ref uint
Index)
{
Data[Index++] = (byte)(src & 0xff);
Data[Index++] = (byte)((src >08) & 0xff);
Data[Index++] = (byte)((src >16) & 0xff);
Data[Index++] = (byte)((src >24) & 0xff);
Data[Index++] = (byte)((src >32) & 0xff);
Data[Index++] = (byte)((src >40) & 0xff);
Data[Index++] = (byte)((src >48) & 0xff);
Data[Index++] = (byte)((src >56) & 0xff);
}

The Pack looks okay, but I have spent hours on the UnPack and I just
seem to be confusing myself.

Can anyone tell me what is wrong with my unpack method?

Thanks

Stuart

Mar 23 '07 #1
5 8158
On Mar 23, 9:11 am, stuie_nor...@yahoo.com.au wrote:
I am trying to write a method to unpack a byte array into an Uint64.
But the results are wrong.
In what circumstances?
A quick test app works for me, but I've only tried one value.

Can you provide a short but complete program which demonstrates the
problem?
See http://pobox.com/~skeet/csharp/complete.html for what I mean by
that.

Personally, I would use BitConverter (or my own EndianBitConverter,
which allows you to specify endian-ness) to do this.

Matters of style you may wish to note:
1) Use "out" instead of "ref" when you don't care about the input
value
2) Prefer return values to pass-by-ref usually - I would certainly
make Unpack return a ulong instead of taking one by reference
3) Parameter names are conventionally camelCased rather than
PascalCased
4) Your method names use "Uint64" instead of "UInt64" (capitalise the
I)

I guess passing the index by reference allows for some useful use
cases, but it's a bit of a pain in others (where you just want to pass
0, for instance).

Jon

Mar 23 '07 #2
Hi Group,

Here is an example that demonstrates the issue with my method. I
would expect the result of the method to display the number after the
PACK and UNPACK.

Pack 2147483648, UnPack 18446744071562067968.

Can anyone tell me what I am doing wrong with my UnPack Method?

Thanks

Stuart

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace UtilityTester
{
class Program
{
public static void PackUint64(ulong src, byte[] Data, ref uint
Index)
{
Data[Index++] = (byte)(src & 0xff);
Data[Index++] = (byte)((src >08) & 0xff);
Data[Index++] = (byte)((src >16) & 0xff);
Data[Index++] = (byte)((src >24) & 0xff);
Data[Index++] = (byte)((src >32) & 0xff);
Data[Index++] = (byte)((src >40) & 0xff);
Data[Index++] = (byte)((src >48) & 0xff);
Data[Index++] = (byte)((src >56) & 0xff);
}
public static void UnpackUint64(ref UInt64 dst, byte[] Data,
ref uint Index)
{
dst = Data[Index++];
dst += (UInt64)((Data[Index++] & 0xffff) << 08);
dst += (UInt64)((Data[Index++] & 0xffff) << 16);
dst += (UInt64)((Data[Index++] & 0xffff) << 24);
dst += (UInt64)((Data[Index++] & 0xffff) << 32);
dst += (UInt64)((Data[Index++] & 0xffff) << 40);
dst += (UInt64)((Data[Index++] & 0xffff) << 48);
dst += (UInt64)((Data[Index++] & 0xffff) << 56);
}
static void Main(string[] args)
{
byte[] b = new byte[10];
uint ipack = 0;
uint iunpack = 0;
UInt64 number64 = 0;
UInt64 result64 = 0;

number64 = 2147483648;
ipack = 0;
PackUint64(number64, b, ref ipack);
iunpack = 0;
result64 = 0;
UnpackUint64(ref result64, b, ref iunpack);
Console.WriteLine("Pack {0}, UnPack {1}",
number64,result64);
Thread.Sleep(50000000);
}
}
}

Mar 23 '07 #3
On Mar 23, 9:35 am, stuie_nor...@yahoo.com.au wrote:
Here is an example that demonstrates the issue with my method. I
would expect the result of the method to display the number after the
PACK and UNPACK.

Pack 2147483648, UnPack 18446744071562067968.

Can anyone tell me what I am doing wrong with my UnPack Method?
Yup - sorry not to have spotted it before. When you're left-shifting,
you're doing it with an int. Instead, you need to cast to a ulong
first. Here's the corrected method:

public static void UnpackUint64(ref UInt64 dst,
byte[] Data,
ref uint Index)
{
dst = Data[Index++];
dst += ((UInt64)Data[Index++]) << 08;
dst += ((UInt64)Data[Index++]) << 16;
dst += ((UInt64)Data[Index++]) << 24;
dst += ((UInt64)Data[Index++]) << 32;
dst += ((UInt64)Data[Index++]) << 40;
dst += ((UInt64)Data[Index++]) << 48;
dst += ((UInt64)Data[Index++]) << 56;
}

Jon

Mar 23 '07 #4
Jon,

Thanks for the reply. That is great. I was just staring at it an not
noticing what is wrong.

Any ideas why I the error

"Cannot implicitily convert type 'int' to 'ushort'. An explicit
conversion exists (are you missing a cast?)"

public static void UnpackUInt16(ref UInt16 dst, byte[] Data,
ref uint Index)
{
dst = (UInt16)Data[Index++];
dst += (UInt16)Data[Index++] << 08; // This line
}

Thanks

Stuart

Mar 24 '07 #5
<st**********@yahoo.com.auwrote:
Thanks for the reply. That is great. I was just staring at it an not
noticing what is wrong.

Any ideas why I the error

"Cannot implicitily convert type 'int' to 'ushort'. An explicit
conversion exists (are you missing a cast?)"
Yes - only the following left shift operators are predefined:

int operator <<(int x, int count);
uint operator <<(uint x, int count);
long operator <<(long x, int count);
ulong operator <<(ulong x, int count);

So in this case, your ushort is converted to an int, and the result is
an int. You need to cast the result to a ushort.

Note that in this case you don't need the cast on the first line, and
the cast on the second line only needs to be for the whole expression -
the only reason you needed the cast for Data[Index++] in the ulong
situation is because you needed to make it use the last of the operator
overloads listed above rather than the first. So your method can be:

public static void UnpackUInt16(ref UInt16 dst, byte[] Data,
ref uint Index)
{
dst = Data[Index++];
dst += (UInt16)(Data[Index++] << 08);
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 24 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

6 posts views Thread by serpent17 | last post: by
2 posts views Thread by Nadav | last post: by
reply views Thread by Gary Herron | last post: by
reply views Thread by Gary Herron | last post: by
19 posts views Thread by JRough | last post: by
7 posts views Thread by Andrus | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.