2009-04-02 56 views
6

Tôi có một mảng byte được tạo bởi trình tạo số ngẫu nhiên. Tôi muốn đặt nó vào trong các bit STL.Chuyển đổi Byte Array thành Bitset

Thật không may, nó trông giống như BitSet chỉ hỗ trợ các nhà thầu sau:

  1. Một chuỗi của 1 và 0 của như "10.101.011"
  2. Một unsigned dài. (mảng byte của tôi sẽ dài hơn)

Giải pháp duy nhất tôi có thể nghĩ bây giờ là đọc từng mảng byte và tạo chuỗi 1 và 0. Có ai có một giải pháp hiệu quả hơn?

Trả lời

7

Một cái gì đó như thế này? (Không chắc chắn nếu mẫu ma thuật làm việc ở đây như tôi mong đợi Tôi gỉ trong C++..)

std::bitset bytesToBitset<int numBytes>(byte *data) 
{ 
    std::bitset<numBytes * CHAR_BIT> b; 

    for(int i = 0; i < numBytes; ++i) 
    { 
     byte cur = data[i]; 
     int offset = i * CHAR_BIT; 

     for(int bit = 0; bit < CHAR_BIT; ++bit) 
     { 
      b[offset] = cur & 1; 
      ++offset; // Move to next bit in b 
      cur >>= 1; // Move to next bit in array 
     } 
    } 

    return b; 
} 
0

bạn có thể khởi tạo bitet từ luồng. Tôi không thể nhớ làm thế nào để wrangle một byte [] vào một dòng, nhưng ...

từ http://www.sgi.com/tech/stl/bitset.html

bitset<12> x; 

    cout << "Enter a 12-bit bitset in binary: " << flush; 
    if (cin >> x) { 
    cout << "x =  " << x << endl; 
    cout << "As ulong: " << x.to_ulong() << endl; 
    cout << "And with mask: " << (x & mask) << endl; 
    cout << "Or with mask: " << (x | mask) << endl; 
    } 
+0

Tôi chỉ cố gắng đó, và nó yêu cầu đầu vào chỉ là 1 hoặc 0 – Unknown

3

Có một constructor thứ 3 cho bitset<> - phải mất không có thông số và thiết lập tất cả các bit để 0. Tôi nghĩ bạn sẽ cần phải sử dụng nó sau đó đi qua mảng gọi set() cho mỗi bit trong mảng byte đó là 1.

Một chút sức mạnh vũ phu, nhưng nó sẽ hoạt động. Sẽ có một chút phức tạp để chuyển đổi byte-index và bit offset trong mỗi byte thành chỉ số bitet, nhưng không có gì là một chút suy nghĩ (và có thể chạy qua bên dưới trình gỡ lỗi) sẽ không giải quyết được. Tôi nghĩ rằng nó rất có thể đơn giản và hiệu quả hơn là cố gắng chạy mảng thông qua một chuyển đổi chuỗi hoặc một dòng.

2

Guys, tôi đã dành rất nhiều thời gian bằng cách viết một hàm reverse (bitset -> byte/char mảng). Có đó là:

bitset<SIZE> data = ... 

    // bitset to char array 
    char current = 0; 
    int offset = 0; 
    for (int i = 0; i < SIZE; ++i) { 
     if (data[i]) { // if bit is true 
      current |= (char)(int)pow(2, i - offset * CHAR_BIT); // set that bit to true in current masked value 
     } // otherwise let it to be false 
     if ((i + 1) % CHAR_BIT == 0) { // every 8 bits 
      buf[offset++] = current; // save masked value to buffer & raise offset of buffer 
      current = 0; // clear masked value 
     } 
    } 

    // now we have the result in "buf" (final size of contents in buffer is "offset") 
2

Vâng, chúng ta hãy thành thật, tôi đã chán và bắt đầu nghĩ rằng phải có một cách nhanh hơn một chút so với thiết lập mỗi bit.

template<int numBytes> 
std::bitset<numBytes * CHARBIT bytesToBitset(byte *data) 
{ 
    std::bitset<numBytes * CHAR_BIT> b = *data; 

    for(int i = 1; i < numBytes; ++i) 
    { 
     b <<= CHAR_BIT; // Move to next bit in array 
     b |= data[i]; // Set the lowest CHAR_BIT bits 
    } 

    return b; 
} 

Điều này thực sự nhanh hơn một chút, ít nhất là mảng byte nhỏ hơn 30 phần tử (tùy thuộc vào cờ tối ưu hóa của bạn được chuyển đến trình biên dịch). Mảng lớn hơn thời gian đó và thời gian được sử dụng bằng cách dịch chuyển bitet giúp thiết lập nhanh hơn mỗi bit.

0

Đây là triển khai của tôi bằng cách sử dụng lập trình mẫu meta.
Vòng lặp được thực hiện trong thời gian biên dịch.
tôi mất @strager phiên bản, sửa đổi nó để chuẩn bị cho TMP:

  • để thay đổi lặp (vì vậy mà tôi có thể làm cho đệ quy từ nó);
  • giảm số lượng biến được sử dụng.

Modified phiên bản với các vòng trong một thời gian chạy:

template <size_t nOfBytes> 
void bytesToBitsetRunTimeOptimized(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { 
    for(int i = nOfBytes - 1; i >= 0; --i) { 
    for(int bit = 0; bit < CHAR_BIT; ++bit) { 
     result[i * CHAR_BIT + bit] = ((arr[i] >> bit) & 1); 
    } 
    } 
} 

phiên bản TMP dựa trên nó:

template<size_t nOfBytes, int I, int BIT> struct LoopOnBIT { 
    static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { 
    result[I * CHAR_BIT + BIT] = ((arr[I] >> BIT) & 1); 
    LoopOnBIT<nOfBytes, I, BIT+1>::bytesToBitset(arr, result); 
    } 
}; 
// stop case for LoopOnBIT 
template<size_t nOfBytes, int I> struct LoopOnBIT<nOfBytes, I, CHAR_BIT> { 
    static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { } 
}; 

template<size_t nOfBytes, int I> struct LoopOnI { 
    static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { 
    LoopOnBIT<nOfBytes, I, 0>::bytesToBitset(arr, result); 
    LoopOnI<nOfBytes, I-1>::bytesToBitset(arr, result); 
    } 
}; 
// stop case for LoopOnI 
template<size_t nOfBytes> struct LoopOnI<nOfBytes, -1> { 
    static inline void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { } 
}; 

template <size_t nOfBytes> 
void bytesToBitset(uint8_t* arr, std::bitset<nOfBytes * CHAR_BIT>& result) { 
    LoopOnI<nOfBytes, nOfBytes - 1>::bytesToBitset(arr, result); 
} 

mã khách hàng:

uint8_t arr[]={0x6A}; 
    std::bitset<8> b; 
    bytesToBitset<1>(arr,b); 
Các vấn đề liên quan