views:

125

answers:

5

We have a device which has a 10 byte serial number which must be read into our application and stored into a .net datatype. In the device it is stored as an unsigned 10-byte (80-bit) number. I don't expect we will be performing any mathematical operations on this number, but only displaying it to the user.

The .NET framework doesn't have a built in UNIT128 to store this datatype. My suggestion for storing this datatype is to create a 10 element byte array and read in the data into this array. Are there any better solutions to this problem?

Note: I have seen in this question that a GUID is a 128 byte signed integer, but it seems like a bad idea to use a GUID in this fashion. Any other suggestions?

+4  A: 

You should use a byte array.

SLaks
Glad to hear that I'm on the same page, I also think this is the simplest option. Thanks for the second opinion.
CrimsonX
A: 

If you're not doing calculations on the number, what wrong with System.String?

pblasucci
+1  A: 

If you're only displaying it, why not use a string? If you want additional security against accidental changes, you could even wrap that into some business object.

AllenG
Because then you get encoding issues.
SLaks
@SLacks: what encoding issues? I may be missing something, but if its only used for display to the user how is encoding a problem. Even pulling it from the DB is a (relatively) simple Cast() or Convert() call.
AllenG
A: 

You have few options. Any they depend on how you will use the data. You can pack it into a Guid, use a byte array, use a custom Struct, or pack it as Base64 or HEX and stuff it into a string.

[StructLayout( LayoutKind.Explicit)]
public struct MyStruct
{
    public MyStruct(byte[] buffer)
    {
        if (buffer.Length != 10)
            throw new ArgumentOutOfRangeException();
        High = BitConverter.ToUInt16(buffer, 0);
        Low = BitConverter.ToUInt64(buffer, 2);
    }
    [FieldOffset(0)]
    public ushort High;  //2 bytes
    [FieldOffset(2)]
    public ulong Low;    //8 bytes

    public byte[] Bytes
    {
        get
        {
            return BitConverter.GetBytes(High)
                .Concat(BitConverter.GetBytes(Low))
                .ToArray();
        }
    }
    public override string ToString()
    {
        return Convert.ToBase64String(Bytes);
    }
    public static MyStruct Parse(string toParse)
    {
        var bytes = Convert.FromBase64String(toParse);
        return new MyStruct(bytes);
    }
}
Matthew Whited
The only point of the `struct` is to marshal it correctly.
SLaks
That is why it depends on the why of the data. There is nothing wrong with using a struct like a C union if you can decode the input data. Say the data could be decoded like a VIN code. You could use the `struct` byte packing to even overlay enums and flags on the related parts.
Matthew Whited
It's also very possible that the 10 bytes of data from the device is really the Serial Number encoded in ASCII. And if that's the case then there is nothing wrong with using `Encoding.ASCII.GetString(...)`
Matthew Whited
+1  A: 

I agree with @SLaks, you should use a byte array. However, BigInteger, http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx, might also work, since it theoretically has no lower/upper bounds. This is for .NET 4 only. Byte array would still be a better choice though.

Jeff Schumacher
Its good to know this datatype also exists. Thanks for the info
CrimsonX
This is only available in .Net 4.
SLaks
@SLaks - Good point, I forgot to mention that.
Jeff Schumacher