在字节数组中设置特定位

Nev*_*ets 8 c# arrays bit-shift

我想知道如何设置16字节数组(128位)中的特定位.

例如......如果我想在数组中设置第9位,我期望:

{00,80,00,00,00,00,00,00,00,00,00,00,00,00,00,00}

如果我想设置第125位......

{00,00 00,00,00,00,00,00,00,00,00,00,00,00,00,08}

我已经研究过使用位移,但对于如何使用由128位组成的数组进行位移而感到困惑.有没有办法打破这个大小的数组并以较小的字节块进行评估?任何帮助,将不胜感激.

das*_*ght 23

选择特定位的过程包括两个步骤:

  • 挑选字节,然后
  • 挑选一下.

拾取字节很简单:您需要做的就是将位索引除以字节中的位数 - 即除以8:

int byteIndex = bitIndex / 8;
Run Code Online (Sandbox Code Playgroud)

现在您知道要使用的字节,计算您要访问的位.为此你需要计算除法的余数为8,如下所示:

int bitInByteIndex = bitIndex % 8;
Run Code Online (Sandbox Code Playgroud)

有了这两个索引,就可以轻松访问该位:1 << bitInByteIndex用作掩码,如下所示:

byte mask = (byte)(1 << bitInByteIndex);
bool isSet = (bytes[byteIndex] & mask) != 0;
// set to 1
bytes[byteIndex] |= mask;
// Set to zero
bytes[byteIndex] &= ~mask;
// Toggle
bytes[byteIndex] ^= mask;
Run Code Online (Sandbox Code Playgroud)


Håk*_*edt 13

你可以使用BitArray:

byte[] bytearray = new byte[16];

var bitArray = new BitArray(bytearray);

bitArray.Set(8, true);

bitArray.CopyTo(bytearray, 0);
Run Code Online (Sandbox Code Playgroud)


Jen*_*ens 7

直接来自字节数组,您最快的解决方案可能是使用BitArray.- http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx

例如,这将是这样的:

public void BitManimulation() 
{
    //Ill just use 2 bytes here for demonstration, get your 16 bytes here.
    byte[] bytes = new[] { (byte)250, (byte)250 };

    //Convert your bytes to a BitArray.
    BitArray array = new BitArray(bytes);
    array[3] = !array[3]; // Flip
    array[4] = false; // 0
    array[5] = true; // 1

    //Convert back to bytes.
    byte[] bytes2 = new byte[2];
    array.CopyTo(bytes2,0);

    Console.WriteLine(bytes2[0]);
    Console.WriteLine(bytes2[1]);
}
Run Code Online (Sandbox Code Playgroud)

现在这会带来性能损失.

所以作为替代方案,你有BitVector32需要你将4个字节的块转换为整数... - http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32.aspx

最后,您可以进行位移,XOR等以产生所需的结果.因为@dasblinkenlight已经给那个病人留下了一个很好的答案,所以请留下你解释的事情.^

这里有一些基于他的帖子的快速帮助方法:

public static class ByteArrayExt
{
    public static byte[] SetBit(this byte[] self, int index, bool value)
    {
        int byteIndex = index / 8;
        int bitIndex = index % 8;
        byte mask = (byte)(1 << bitIndex);

        self[byteIndex] = (byte)(value ? (self[byteIndex] | mask) : (self[byteIndex] & ~mask));
        return self;
    }

    public static byte[] ToggleBit(this byte[] self, int index)
    {
        int byteIndex = index / 8;
        int bitIndex = index % 8;
        byte mask = (byte)(1 << bitIndex);

        self[byteIndex] ^= mask;
        return self;
    }

    public static bool GetBit(this byte[] self, int index)
    {
        int byteIndex = index / 8;
        int bitIndex = index % 8;
        byte mask = (byte)(1 << bitIndex);

        return (self[byteIndex] & mask) != 0;
    }
}
Run Code Online (Sandbox Code Playgroud)