如何从一个字节数组获得一个未签名的长?

时间:2022-11-01 20:09:46

I have an incoming byte array from a piece of test equipment. The byte array can either be two or four bytes long. I wrote the following code to convert these byte array's into unsigned longs:

我有一个来自测试设备的传入字节数组。字节数组可以是两个或四个字节长。我编写了下面的代码,将这些字节数组转换成无符号的longs:

private ulong GetUlongFrom2Bytes(byte MSB, byte LSB)
{
    return (ulong)((MSB << 8) + (LSB));
}

private ulong GetUlongFrom4Bytes(byte MSB, byte msb, byte lsb, byte LSB)
{
    return (ulong)((MSB << 24) + (msb << 16) + (lsb << 8) + (LSB));
}

Conversely, for going the opposite direction, I do the following code:

相反地,对于相反的方向,我做以下代码:

private byte[] Get4Bytes(ulong parm1)
{
    byte[] retVal = new byte[4];

    retVal[0] = (byte)((parm1 >> 24) & 0xFF);
    retVal[1] = (byte)((parm1 >> 16) & 0xFF);
    retVal[2] = (byte)((parm1 >> 8) & 0xFF);
    retVal[3] = (byte)(parm1 & 0xFF);

    return retVal;
}

private byte[] Get8Bytes(ulong parm1, ulong parm2)
{
    byte[] retVal = new byte[8];

    Array.Copy(Get4Bytes(parm1), 0, retVal, 0, 4);
    Array.Copy(Get4Bytes(parm2), 0, retVal, 4, 4);

    return retVal;
}

I'm trying to debug my code for controlling this piece of equipment and I'd just like a sanity check from you guys here on SO to confirm that this code is written correctly for what I'm trying to do.

我正在调试用于控制这部分设备的代码,我想从你们这里得到一个完整的检查,以便确认这段代码是为我正在做的事情而正确编写的。

2 个解决方案

#1


3  

Assuming you want big-endian encoding, then yes: that'll be fine. You can also use BitConverter, but I think you are right not to - it involves extra array allocations, and forces the system's endianness on you (often little-endian).

假设您希望使用big-endian编码,那么yes:没问题。您也可以使用位转换器,但我认为您没有这样做是对的——它涉及额外的数组分配,并迫使系统的机缘凑巧(通常是little-endian)。

Generally, I would recommend such code works with a buffer/offset API, though, for simplicity and efficiency - i.e.

一般来说,我建议这样的代码使用缓冲区/偏移量API,但是,为了简单和高效——例如。

private void Write32(ulong value, byte[] buffer, int offset)
{
    buffer[offset++] = (byte)((value >> 24) & 0xFF);
    buffer[offset++] = (byte)((value >> 16) & 0xFF);
    buffer[offset++] = (byte)((value >> 8) & 0xFF);
    buffer[offset] = (byte)(value & 0xFF);
}

#2


1  

This would do it:

这将这么做:

static ulong SliceValue(byte[] bytes, int start, int length)
{
    var bytes = bytes.Skip(start).Take(length);

    ulong acc = 0;
    foreach (var b in bytes) acc = (acc * 0x100) + b;

    return acc;
}

#1


3  

Assuming you want big-endian encoding, then yes: that'll be fine. You can also use BitConverter, but I think you are right not to - it involves extra array allocations, and forces the system's endianness on you (often little-endian).

假设您希望使用big-endian编码,那么yes:没问题。您也可以使用位转换器,但我认为您没有这样做是对的——它涉及额外的数组分配,并迫使系统的机缘凑巧(通常是little-endian)。

Generally, I would recommend such code works with a buffer/offset API, though, for simplicity and efficiency - i.e.

一般来说,我建议这样的代码使用缓冲区/偏移量API,但是,为了简单和高效——例如。

private void Write32(ulong value, byte[] buffer, int offset)
{
    buffer[offset++] = (byte)((value >> 24) & 0xFF);
    buffer[offset++] = (byte)((value >> 16) & 0xFF);
    buffer[offset++] = (byte)((value >> 8) & 0xFF);
    buffer[offset] = (byte)(value & 0xFF);
}

#2


1  

This would do it:

这将这么做:

static ulong SliceValue(byte[] bytes, int start, int length)
{
    var bytes = bytes.Skip(start).Take(length);

    ulong acc = 0;
    foreach (var b in bytes) acc = (acc * 0x100) + b;

    return acc;
}