2009-02-18 10 views
27

में कनवर्ट करें मेरे पास 812 की लंबाई के साथ BitArray है, और मुझे इसे byte में बदलने के लिए एक फ़ंक्शन चाहिए। यह कैसे करना है?BitArray से बाइट

विशेष रूप से, मैं ConvertToByte का सही समारोह की जरूरत है:

BitArray bit = new BitArray(new bool[] 
{ 
    false, false, false, false, 
    false, false, false, true 
}); 

//How to write ConvertToByte 
byte myByte = ConvertToByte(bit); 
var recoveredBit = new BitArray(new[] { myByte }); 
Assert.AreEqual(bit, recoveredBit); 

उत्तर

40

यह काम करना चाहिए:

byte ConvertToByte(BitArray bits) 
{ 
    if (bits.Count != 8) 
    { 
     throw new ArgumentException("bits"); 
    } 
    byte[] bytes = new byte[1]; 
    bits.CopyTo(bytes, 0); 
    return bytes[0]; 
} 
+6

मन: यह रिवर्स ऑर्डर में बिट्स की गणना करता है, उदा। उदाहरण से बिटअरे 128 में परिवर्तित हो जाएगा, 1 नहीं! – tehvan

+0

यह रिवर्स ऑर्डर में क्यों होता है? –

+1

@ कॉर्नेलिजिपेटक: यह वही तरीका है जो बिटरएरे काम करता है, जिस तरह से यह मूल्यों की प्रतिलिपि बनाने का विकल्प चुनता है। –

4

इस चाल करना चाहिए। हालांकि पिछले जवाब काफी बेहतर विकल्प है।

public byte ConvertToByte(BitArray bits) 
    { 
     if (bits.Count > 8) 
      throw new ArgumentException("ConvertToByte can only work with a BitArray containing a maximum of 8 values"); 

     byte result = 0; 

     for (byte i = 0; i < bits.Count; i++) 
     { 
      if (bits[i]) 
       result |= (byte)(1 << i); 
     } 

     return result; 
    } 

उदाहरण में आपने पोस्ट किया है जिसके परिणामस्वरूप बाइट 0x80 होगा। दूसरे शब्दों में BitArray में पहला मान लौटा बाइट में पहले बिट से मेल खाता है।

5

एक गरीब आदमी का समाधान:

protected byte ConvertToByte(BitArray bits) 
{ 
    if (bits.Count != 8) 
    { 
     throw new ArgumentException("illegal number of bits"); 
    } 

    byte b = 0; 
    if (bits.Get(7)) b++; 
    if (bits.Get(6)) b += 2; 
    if (bits.Get(5)) b += 4; 
    if (bits.Get(4)) b += 8; 
    if (bits.Get(3)) b += 16; 
    if (bits.Get(2)) b += 32; 
    if (bits.Get(1)) b += 64; 
    if (bits.Get(0)) b += 128; 
    return b; 
} 
27

थोड़ा देर से पोस्ट है, लेकिन यह मेरे लिए काम करता है:

string text = "Test"; 
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(text); 
BitArray bits = new BitArray(bytes); 
bytes[] bytesBack = BitArrayToByteArray(bits); 
string textBack = System.Text.Encoding.ASCII.GetString(bytesBack); 
// bytes == bytesBack 
// text = textBack 

:

साथ
public static byte[] BitArrayToByteArray(BitArray bits) 
{ 
    byte[] ret = new byte[(bits.Length - 1)/8 + 1]; 
    bits.CopyTo(ret, 0); 
    return ret; 
} 

काम करता है।

+11

" बिट्स। लम्बाई/8 "के बजाय, आपको" (बिट्स। लम्बाई - 1)/8 + 1 "का उपयोग करना चाहिए, अन्यथा यदि बिटअरे की लंबाई 7 है, तो आपके बाइट सरणी खाली रहो "- 1" भाग सुनिश्चित करता है कि 8 का एक से अधिक एक साथ वापस नहीं आएगा। Http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/503201#503201 – iano

+1

अच्छा बिंदु के लिए धन्यवाद। एक गणित। मैक्स (1, बिट्स। लम्बाई/8) भी मुझे लगता है कि काम करेगा (थोड़ा और पठनीय)। मैं हमेशा 8 बिट बाइट्स पर काम करता हूं इसलिए मैंने अंडरफ्लो हालत को नहीं माना है। –

+1

@TeddHansen 15 के बारे में क्या? –

2

यह परम होना चाहिए। सरणी की किसी भी लंबाई के साथ काम करता है।

private List<byte> BoolList2ByteList(List<bool> values) 
    { 

     List<byte> ret = new List<byte>(); 
     int count = 0; 
     byte currentByte = 0; 

     foreach (bool b in values) 
     { 

      if (b) currentByte |= (byte)(1 << count); 
      count++; 
      if (count == 7) { ret.Add(currentByte); currentByte = 0; count = 0; };    

     } 

     if (count < 7) ret.Add(currentByte); 

     return ret; 

    } 
+0

मेरा मानना ​​है कि यहां एक बग है - क्योंकि 'गिनती ++;' पहले से ही निकाल दी गई है, अगली पंक्ति 'if (count == 8) {...}' –

0
byte GetByte(BitArray input) 
{ 
    int len = input.Length; 
    if (len > 8) 
    len = 8; 
    int output = 0; 
    for (int i = 0; i < len; i++) 
    if (input.Get(i)) 
     output += (1 << (len - 1 - i)); //this part depends on your system (Big/Little) 
     //output += (1 << i); //depends on system 
    return (byte)output; 
} 

चीयर्स!

0

लिटिल एंडियन बाइट सरणी कनवर्टर: बिट बिट में पहली बिट ("0" के साथ अनुक्रमित) कम से कम महत्वपूर्ण बिट (बिट-ऑक्टेट में सही बिट) का प्रतिनिधित्व करने के लिए माना जाता है जिसे बाइनरी के रूप में "शून्य" या "एक" के रूप में व्याख्या किया जाता है ।

public static class BitArrayExtender { 

    public static byte[] ToByteArray(this BitArray bits) { 

     const int BYTE = 8; 
     int length = (bits.Count/BYTE) + ((bits.Count % BYTE == 0) ? 0 : 1); 
     var bytes = new byte[ length ]; 

     for (int i = 0; i < bits.Length; i++) { 

      int bitIndex = i % BYTE; 
      int byteIndex = i/BYTE; 

      int mask = (bits[ i ] ? 1 : 0) << bitIndex; 
      bytes[ byteIndex ] |= (byte)mask; 

     }//for 

     return bytes; 

    }//ToByteArray 

}//class 
1

इसके अलावा @JonSkeet जवाब देने के लिए आप झटका के रूप में सामान्य विधि का उपयोग कर सकते हैं:

public static byte ToByte(this BitArray bits) 
     { 
      if (bits.Count != 8) 
      { 
       throw new ArgumentException("bits"); 
      } 
      byte[] bytes = new byte[1]; 
      bits.CopyTo(bytes, 0); 
      return bytes[0]; 
     } 

और तरह का उपयोग करें:

BitArray foo = new BitArray(new bool[] 
{ 
    false, false, false, false,false, false, false, true 
}); 

foo.ToByte(); 
0

दुर्भाग्य से, BitArray वर्ग आंशिक रूप से नेट में कार्यान्वित किया जाता कोर क्लास (यूडब्ल्यूपी)। उदाहरण के लिए बिटरायर क्लास CopyTo() और गणना() विधियों को कॉल करने में असमर्थ है। मैं इस विस्तार लिखा खाई को पाटने के:

public static IEnumerable<Byte> ToBytes(this BitArray bits, bool MSB = false) 
    { 
     int bitCount = 7; 
     int outByte = 0; 

     foreach (bool bitValue in bits) 
     { 
      if (bitValue) 
       outByte |= MSB ? 1 << bitCount : 1 << (7 - bitCount); 
      if (bitCount == 0) 
      { 
       yield return (byte) outByte; 
       bitCount = 8; 
       outByte = 0; 
      } 
      bitCount--; 
     } 
     // Last partially decoded byte 
     if (bitCount < 7) 
      yield return (byte) outByte; 
    } 
} 

विधि एक बाइट सरणी LSB (कम महत्वपूर्ण बाइट) लॉजिक का उपयोग करने के लिए BitArray डीकोड। यह एक ही तर्क है जिसे बिटरायरे वर्ग द्वारा उपयोग किया जाता है। सही पर सेट एमएसबी पैरामीटर के साथ विधि को कॉल करने से एक एमएसबी डीकोडेड बाइट अनुक्रम उत्पन्न होगा। इस मामले में, याद रखें कि आपको अंतिम आउटपुट बाइट संग्रह को भी उलट करने की आवश्यकता है।

संबंधित मुद्दे