HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Numbers to byte-arrays and back

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arraysbytenumbersbackand

Problem

As the title explains, this is a series of extension methods that convert certain numeric types to and from byte-arrays, for certain actions which work better on byte-array types than numeric types.

Any and all suggestions are welcome, I am also attaching the Unit Tests.

```
///
/// Provides extension methods to convert certian base types to and from a byte-array.
///
public static class NumberByteArrayExtensions
{
///
/// Converts a uint value to a byte[].
///
/// The uint value to convert.
/// A byte[] representing the uint value.
public static byte[] ToByteArray(this uint value)
{
var size = 4;

var result = new byte[size];

for (var i = 0; i > bitOffset);
}

return result;
}

///
/// Converts a byte[] to a uint value.
///
/// The byte[] to convert.
/// A uint that represents the converted byte[].
public static uint ToUInt32(this byte[] data)
{
var requiredSize = 4;

if (data.Length != requiredSize)
{
throw new ArgumentException($"The byte-array \"{nameof(data)}\" must be exactly {requiredSize} bytes.");
}

var result = 0u;

for (var i = 0; i
/// Converts an int value to a byte[].
///
/// The int to convert.
/// A byte[] representing the int value.
public static byte[] ToByteArray(this int value)
{
var t = (uint)value;

return t.ToByteArray();
}

///
/// Converts a byte[] to an int value.
///
/// The byte[] to convert.
/// An int value representing the byte[].
public static int ToInt32(this byte[] data)
{
var requiredSize = 4;

if (data.Length != requiredSize)
{
throw new ArgumentException($"The byte-array \"{nameof(data)}\" must be exactly {requiredSize} bytes.");
}

return (int)data.ToUInt32();
}

///
/// Converts a ulong to a byte[].
///
/// The ul

Solution

First of all, I agree with others, you could replace lines

var size = 4;
var requiredSize = 8;


with

const int size = sizeof(int);
const int requiredSize = sizeof(long);


This removes magic values from the code.

Secondly, your code is hard to understand. For instance:

result[i] = (byte)((value & ((ulong)0xFF > bitOffset);


My suggestion is to use structs with [StructLayout(LayoutKind.Explicit)] attribute:

[StructLayout(LayoutKind.Explicit)]
public struct UnionInt
{
    [FieldOffset(0)]
    public readonly int Value;
    [FieldOffset(0)]
    private readonly byte byte0;
    [FieldOffset(1)]
    private readonly byte byte1;
    [FieldOffset(2)]
    private readonly byte byte2;
    [FieldOffset(3)]
    private readonly byte byte3;

    public byte[] Bytes
    {
        get { return new[] { byte0, byte1, byte2, byte3 }; }
        // Or { byte3, byte2, byte1, byte0 } to change endianess
    }

    public UnionInt(int value)
    {
        byte0 = byte1 = byte2 = byte3 = 0;
        Value = value;
    }
}

Code Snippets

var size = 4;
var requiredSize = 8;
const int size = sizeof(int);
const int requiredSize = sizeof(long);
result[i] = (byte)((value & ((ulong)0xFF << bitOffset)) >> bitOffset);
[StructLayout(LayoutKind.Explicit)]
public struct UnionInt
{
    [FieldOffset(0)]
    public readonly int Value;
    [FieldOffset(0)]
    private readonly byte byte0;
    [FieldOffset(1)]
    private readonly byte byte1;
    [FieldOffset(2)]
    private readonly byte byte2;
    [FieldOffset(3)]
    private readonly byte byte3;

    public byte[] Bytes
    {
        get { return new[] { byte0, byte1, byte2, byte3 }; }
        // Or { byte3, byte2, byte1, byte0 } to change endianess
    }

    public UnionInt(int value)
    {
        byte0 = byte1 = byte2 = byte3 = 0;
        Value = value;
    }
}

Context

StackExchange Code Review Q#108529, answer score: 12

Revisions (0)

No revisions yet.