2014-08-29 67 views
1

我得到一个从byte []数据进行Base64编码的字符串,我必须检查它里面的位。当我得到“AAAB”时,我将它解码为一个字节[],并且当A = {000000}和B = {000001}时,我得到[{00000000} {00000000} {00000001}]。如何检查一个字节的位[]

的事情是,我想指望它咬1.在上述情况下,也就是1位是24号,所以我希望得到24

所以这是我想这样做:

拟议由Scott的解决方案编辑:

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'。 – 2014-08-29 03:24:55

+1

它的“位”或“字节”。 _bites_不是一个字。 – ja72 2014-08-29 03:59:02

回答

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)和去在右边。所以你的输出将是而不是false, false ..., false, true。如果你想要的话,另一种方式 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()在var i的位置16处返回true,而不是位置23(在这种情况下bitData.Length为24)。你知道为什么吗? – Kane 2014-08-29 04:49:27

+0

对不起,32是一个错字23,因为我没有注意到对于构造函数msdn的注释*“数组中的第一个字节表示0到7位,第二个字节表示8到15位,每个字节的最低有效位表示最低索引值“*我已经更新了我的答案,以显示如何使它更像您期望的。 – 2014-08-29 05:58:45

+0

byteData没有Reverse()函数,因为它不是数组。还有另一种方法可以做到吗? – Kane 2014-08-29 06:17:22

1

我曾经写过Extension Method以允许在一个字节内获取和设置各个位;也许这会帮助你。

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 
相关问题