将17bit数据组合成字节数组

发布于 2024-11-08 06:41:52 字数 934 浏览 0 评论 0原文

我在尝试将 17 位数据组移入字节数组时遇到了一些问题。我不想一步步进行,但我无法找出逻辑循环。
我需要这种方式,因为我打算通过像这样组合后将所有字节值相加来计算校验和。
这就是我正在努力解决的问题。

我有 16 个字节数组。数组的前 3 个字节包含我要查找的 17 位。 (来自 [0] 的 8 位,来自 [1] 的 8 位,以及来自 [2] 的 MSB。)

我需要移动这些16 个 17 位值到一个单独的字节数组。

第一个很简单:

int index = 0;
myArray[index++] = driverData[driver][0];            //First byte
myArray[index++] = driverData[driver][1];            //Second byte
myArray[index] = (driverData[driver][2] & 0x80) << 7;  //First bit of the third byte.

从这里开始,尝试任何类型的循环来移动它们变得更加困难。

driver++;<br>
//Take the 7 MSBs from the data array.
myArray[index++] |= (byte)(driverData[driver][0] & 0x7e >> 1);
//This leaves a single bit left over on driverData[driver][0].
myArray[index] = (byte)(driverData[driver][1] & 0x1 << 7);

我想你明白了。难道我做的这一切都是错的吗?有人能指出我正确的方向吗?

I'm having a bit of an issue with trying to move groups of 17bit data in to a byte array. I don't want to have to go through step-by-step, but I can't figure out a logical loop.
I need it this way because I'm meant to calculate a checksum by adding up the all the byte values after combining them like this.
So here is what I am struggling with.

I have 16 byte arrays. The first 3 bytes of the array contain the 17 bits I'm after. (8 bits from [0], 8 bits from [1], and the MSB from [2].)

I need to move these 16 17bit values to one separate byte array.

The first one is easy:

int index = 0;
myArray[index++] = driverData[driver][0];            //First byte
myArray[index++] = driverData[driver][1];            //Second byte
myArray[index] = (driverData[driver][2] & 0x80) << 7;  //First bit of the third byte.

From here though it gets harder to attempt any kind of loop to move these over.

driver++;<br>
//Take the 7 MSBs from the data array.
myArray[index++] |= (byte)(driverData[driver][0] & 0x7e >> 1);
//This leaves a single bit left over on driverData[driver][0].
myArray[index] = (byte)(driverData[driver][1] & 0x1 << 7);

I think you get the picture. Am I doing this all wrong? Can anyone point me in the right direction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

捂风挽笑 2024-11-15 06:41:52

听起来你有一个足够大的素数循环,使得对个别情况进行编码是一个坏主意。这是一个经典的打包问题。您需要一个循环遍历您的目的地,以及一些可以打包更多位的内部代码。您的打包代码应该知道上次迭代有多少位可供使用,需要多少位,并且如果没有足够的位,应该能够增加源指针。

Sounds like you have a prime number loop large enough to make coding the individual cases a bad idea. This is a classic packing problem. You need a loop that iterates through your destination, and some inner code that gets more bits to pack. Your packing code should know how many bits are available to it from the last iteration, how many it needs, and should be able to increment the source pointer if it doesn't have enough.

好的,这看起来可行。我可能需要对其进行更多测试,但这似乎给了我迄今为止所期望的结果。我确信我能以某种方式做得更好。

// ... //
void foo()
{
    //Lets start by getting all the 17bit values from each driver for the board.
    int bitIndex = 7;
    int byteIndex = 0;
    int stopIndex = chipIndex + GetChipCount();
    //Now we start the shiftyness.
    for (int driver = chipIndex; driver < stopIndex; driver++) {
        int userBits =
            (driverData[driver][0] & 0xff) << 9 | (driverData[driver][1]
                               & 0xff)
            << 1 | (driverData[driver][2] & 0x80) >> 7;
        AddBitsToArray(userBits, ref bitIndex, ref byteIndex);

    }
}

/// <summary>
/// Takes the 17 bits, and adds them to the byte array.
/// </summary>
private void AddBitsToArray(int userBits, ref int bitIndex, ref int byteIndex)
{
    int bitCount = 17;
    while (bitCount > 0) {
        //First 8 bytes.
        checksumBytes[byteIndex] |=
            (byte) (((userBits & bitValue(bitCount - 1)) >>
                 (bitCount - 1)) << bitIndex);
        //Move up the bit index to be written to.
        bitIndex--;
        //Decrement the number of bits left to shift.
        bitCount--;
        //If we have gone past the 8th bit, reset the bitIndex and increment the byteIndex.
        if (bitIndex >= 0)
            continue;
        bitIndex = 7;
        byteIndex++;
    }
}

/// <summary>
/// Returns the value of a single bit at the given index.
/// </summary>
private int bitValue(int bitIndex)
{
    return (int)(Math.Pow(2, bitIndex));
}

OK, so this looks to be working. I probably need to test it more, but this seems to be giving me the result I expect so far. I'm sure I could do this better somehow.

// ... //
void foo()
{
    //Lets start by getting all the 17bit values from each driver for the board.
    int bitIndex = 7;
    int byteIndex = 0;
    int stopIndex = chipIndex + GetChipCount();
    //Now we start the shiftyness.
    for (int driver = chipIndex; driver < stopIndex; driver++) {
        int userBits =
            (driverData[driver][0] & 0xff) << 9 | (driverData[driver][1]
                               & 0xff)
            << 1 | (driverData[driver][2] & 0x80) >> 7;
        AddBitsToArray(userBits, ref bitIndex, ref byteIndex);

    }
}

/// <summary>
/// Takes the 17 bits, and adds them to the byte array.
/// </summary>
private void AddBitsToArray(int userBits, ref int bitIndex, ref int byteIndex)
{
    int bitCount = 17;
    while (bitCount > 0) {
        //First 8 bytes.
        checksumBytes[byteIndex] |=
            (byte) (((userBits & bitValue(bitCount - 1)) >>
                 (bitCount - 1)) << bitIndex);
        //Move up the bit index to be written to.
        bitIndex--;
        //Decrement the number of bits left to shift.
        bitCount--;
        //If we have gone past the 8th bit, reset the bitIndex and increment the byteIndex.
        if (bitIndex >= 0)
            continue;
        bitIndex = 7;
        byteIndex++;
    }
}

/// <summary>
/// Returns the value of a single bit at the given index.
/// </summary>
private int bitValue(int bitIndex)
{
    return (int)(Math.Pow(2, bitIndex));
}
陌生 2024-11-15 06:41:52

这是我想出的。该方法的第一部分只是设置一些假输入数据,因此请将其删除并根据需要添加参数。 OutputData 数组不必要地大,但我没有花时间计算它的实际长度。

我使用 170 作为输入值,即 10101010,这对验证很有帮助。

private void BitShift17()
{
    const int NumChunks = 16;
    byte[] DriverData = new byte[]
        {
            170,
            170,
            170
        };
    byte[][] InputData = new byte[NumChunks][];
    for (int n = 0; n < NumChunks; n++)
        InputData[n] = DriverData;

    byte[] OutputData = new byte[NumChunks * 3]; // Unnecessarily large

    int OutputIndex = 0;
    int BitPosition = 0;
    for (int Driver = 0; Driver < InputData.Length; Driver++)
    {
        for (int InputIndex = 0; InputIndex < 3; InputIndex++)
        {
            byte InputByte = InputIndex == 2 ? (byte)(InputData[Driver][InputIndex] & 128) : InputData[Driver][InputIndex];
            if (BitPosition == 0)
            {
                OutputData[OutputIndex] = InputByte;
                if (InputIndex == 2)
                    BitPosition++;
                else
                    OutputIndex++;
            }
            else
            {
                if (InputIndex == 2)
                {
                    OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
                    BitPosition++;
                }
                else
                {
                    OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
                    OutputIndex++;
                    OutputData[OutputIndex] = (byte)(InputByte << 8 - BitPosition);
                }
            }
        }
        if (BitPosition > 7) BitPosition = 0;
    }
}

Here is what I came up with. The first part of the method is just setting up some fake input data, so remove that and add arguments as needed. The OutputData array is unnecessarily large but I didn't spend time to calculate its actual length.

I used 170 as the input value which is 10101010 and was helpful in validation.

private void BitShift17()
{
    const int NumChunks = 16;
    byte[] DriverData = new byte[]
        {
            170,
            170,
            170
        };
    byte[][] InputData = new byte[NumChunks][];
    for (int n = 0; n < NumChunks; n++)
        InputData[n] = DriverData;

    byte[] OutputData = new byte[NumChunks * 3]; // Unnecessarily large

    int OutputIndex = 0;
    int BitPosition = 0;
    for (int Driver = 0; Driver < InputData.Length; Driver++)
    {
        for (int InputIndex = 0; InputIndex < 3; InputIndex++)
        {
            byte InputByte = InputIndex == 2 ? (byte)(InputData[Driver][InputIndex] & 128) : InputData[Driver][InputIndex];
            if (BitPosition == 0)
            {
                OutputData[OutputIndex] = InputByte;
                if (InputIndex == 2)
                    BitPosition++;
                else
                    OutputIndex++;
            }
            else
            {
                if (InputIndex == 2)
                {
                    OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
                    BitPosition++;
                }
                else
                {
                    OutputData[OutputIndex] |= (byte)(InputByte >> BitPosition);
                    OutputIndex++;
                    OutputData[OutputIndex] = (byte)(InputByte << 8 - BitPosition);
                }
            }
        }
        if (BitPosition > 7) BitPosition = 0;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文