Как проверить биты байта []

1

Я получаю строку, которая была кодирована Base64 из данных байта [], и я должен проверить ее внутри.

Когда я получаю "AAAB", я декодирую его в байт [], и как A = {000000} и B = {000001}, я получаю [{00000000} {00000000} {00000001}].

Дело в том, что я хочу подсчитать, какой укус равен 1. В приведенном выше случае бит, который равен 1, - это номер 24, поэтому я хочу получить 24.

Вот что я хотел сделать:

ИЗОБРЕТЕНЫ РЕШЕНИЕМ, ПРЕДЛАГАЕМЫМ СКОТТОМ:

using using System.Linq;

string stringData = "AAAB"; // {000000} {000000} {000000} {000001}
byte[] byteData = Convert.FromBase64String(stringData); // {00000000}{00000000}{00000001}
BitArray bitData = new BitArray(byteData.Reverse().ToArray()); // {100000000000000000000000}

 var i = bitData .Length;
 foreach (bool bit in bitData )
                        {
   if (bit)
   {
     //display i, the bit 1
   }
   j--;
 }

Большое спасибо, Скотт!

  • 1
    byteData[i].Length не должна компилироваться, поскольку byteData[i] является byte .
  • 1
    Это либо bits либо bytes . Укусы это не слово.
Теги:
bytearray

3 ответа

2

Самый простой способ справиться с этим - преобразовать byte[] в BitArray

string stringData = "AAAB"; // {000000} {000000} {000000} {000001}
byte[] byteData = Convert.FromBase64String(stringData); // {00000000}{00000000}{00000001}

BitArray bitData = new BitArray(byteData.Reverse().ToArray()); // {000000000000000000000001}


Console.WriteLine("byteData");
for(var i=0; i < byteData.Length; i++){ //bitData.Length is 32
    var bitValue = byteData[i];
    Console.WriteLine("{0} {1}", i, bitValue);
}

Console.WriteLine();
Console.WriteLine("bitData");
for(var i=0; i < bitData.Length; i++){ //bitData.Length is 32
    var bitValue = bitData[i];
    Console.WriteLine("{0} {1}", i, bitValue);
}

Run this example

Важное замечание: i начну считать с самого важного бита (в настоящее время 1) и направо. поэтому ваш вывод будет true, false,..., false, false not false, false..., false, true. Если вы хотите, то другим способом .Reverse().ToArray() другой .Reverse().ToArray() в bitData.

Console.WriteLine();
Console.WriteLine("reversed");
var reversed = bitData.Cast<bool>().Reverse().ToArray();
for(var i=0; i < reversed.Length; i++){ //bitData.Length is 32
    var bitValue = reversed[i];
    Console.WriteLine("{0} {1}", i, bitValue);
}
  • 0
    Скотт большое спасибо или ваш ответ! Я попробовал это, но в случае AAAB внутри for () возвращает true в позиции 16 переменной i, а не в позиции 23 (в этом случае bitData.Length равно 24). Знаете ли вы, почему?
  • 0
    Извините за это, 32 был опечаткой из 23, для порядка, в котором я не заметил комментарий к msdn для конструктора: «Первый байт в массиве представляет биты с 0 по 7, второй байт представляет биты с 8 по 15 и т. Д. Наименьший значащий бит каждого байта представляет наименьшее значение индекса " Я обновил свой ответ, чтобы показать, как получить его больше, чем вы ожидаете.
Показать ещё 3 комментария
1

Я однажды написал метод расширения, позволяющий получать и устанавливать отдельные биты в байте; возможно, это поможет вам.

public static class MyExtensions
{
    /// <summary>
    /// Sets an individual bit inside a byte, based on the bit number.
    /// </summary>
    /// <param name="aByte">The byte where a bit is to be changed.</param>
    /// <param name="bitNumber">The bit number to read (between 0 and 7).</param>
    /// <param name="value">The value to set the bit to.  0/False or 1/True.</param>
    /// <returns>A byte with the requested bit changed.</returns>
    /// <remarks>The bit number must be between 0 and 7, otherwise an ArgumentOutOfRangeException is thrown.</remarks>
    public static byte SetBit(this byte aByte, byte bitNumber, bool value)
    {
        if (bitNumber > 7) { throw new ArgumentOutOfRangeException("bitNumber", "bitNumber was > 7"); }

        // create a mask of zeros except for the bit we want to modify
        byte mask = 1;
        mask = (byte)(mask << bitNumber);

        if (value)
        {
            // use bitwise-inclusive-or operator to make sure the bit equals 1 (and nothing else is changed)
            aByte = (byte)(aByte | mask);
        }
        else
        {
            // grab the inverse of our original mask (all ones except our bit equals zero)
            mask = (byte)(byte.MaxValue - mask);

            // use bitwise-and operator to make sure our bit equals 0 (and nothing else is changed)
            aByte = (byte)(aByte & mask);
        }
        return aByte;
    }


    /// <summary>
    /// Returns the value of an individual bit from within a byte.
    /// </summary>
    /// <param name="aByte">The byte from which to return bit data.</param>
    /// <param name="bitNumber">The bit number to read (between 0 and 7).</param>
    /// <returns>The value inside the requested bit.  0/False or 1/True.</returns>
    /// <remarks>The bit number must be between 0 and 7, otherwise an ArgumentOutOfRangeException is thrown.</remarks>
    public static bool GetBit(this byte aByte, byte bitNumber)
    {
        if (bitNumber > 7) { throw new ArgumentOutOfRangeException("bitNumber", "bitNumber was > 7"); }

        // create a mask of zeros except for the bit we want to modify
        byte mask = 1;
        mask = (byte)(mask << bitNumber);

        // use bitwise-and operator with our mask; if we get a 1, our bit must have also been a 1
        return (aByte & mask) > 0;
    }

}   

Использовать:

        byte b = 128;
        b = b.SetBit(1, true);

        bool b0 = b.GetBit(0); // false
        bool b1 = b.GetBit(1); // true, because we set it
        bool b2 = b.GetBit(2); // false
        bool b3 = b.GetBit(3); // false
        bool b4 = b.GetBit(4); // false
        bool b5 = b.GetBit(5); // false
        bool b6 = b.GetBit(6); // false
        bool b7 = b.GetBit(7); // true, because we started with 128
0

Надеюсь это поможет.

        string stringData = "AAAB"; 
        byte[] byteData = Convert.FromBase64String(stringData); 
        StringBuilder sb = new StringBuilder("{");

        BitArray ba = new BitArray(byteData);
        for (int i = 0; i < ba.Length; i++)
        {
            sb.Append(ba[i] ? "1" : "0");    //append 1 if true, 0 if false.

            if (((i + 1) % 8 == 0) && ((i + 1) < ba.Length))  //adds formatting
                sb.Append("}{");
        }

        sb.Append("}");
        Console.Write("Bytes:" + sb.ToString());
        Console.Read(); //pause

Ещё вопросы

Сообщество Overcoder
Наверх
Меню