1

文字配列のバイトを逆にする方法を探しています。また、スワップされるバイトの個々のビットを逆にしてから、正しい場所に配置する必要があります。たとえば、arr [0]=00100011およびarr[999]=11010110のchararr[1000]があるとし、arr[0]とarr[999]を交換し、さらにそれぞれのビットを逆にします。したがって、出力はarr [999] = 11000100(arr [0]の反転ビット)およびarr [0] = 01101011(arr [999]の反転ビット)になります。

バイト内でビット反転を行うためのコードがいくつかあります:

static  char reverseByte(char val)
{
    char result = 0;

    int counter = 8;
    while (counter-- < 0)
    {
        result <<= 1;
        result |= (char)(val & 1);
        val = (char)(val >> 1);
    }

    return result;
}

ただし、これは、バイトスワップを実行するために外部ループを実行してから、内部の各バイトに対して上記の小さなループを実行することを意味します。つまり、上記の場合は1000です。これは正しいアプローチですか?これを達成するためのより良い方法はありますか?どんな助けでも大歓迎です。

4

4 に答える 4

1

これはどう?:

#include <stdio.h>
#include <limits.h>

#if CHAR_BIT != 8
#error char is expected to be 8 bits
#endif

unsigned char RevByte(unsigned char b)
{
  static const unsigned char t[16] =
  {
    0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
    0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
  };
  return t[b >> 4] | (t[b & 0xF] << 4);
}

void RevBytes(unsigned char* b, size_t c)
{
  size_t i;
  for (i = 0; i < c / 2; i++)
  {
    unsigned char t = b[i];
    b[i] = RevByte(b[c - 1 - i]);
    b[c - 1 - i] = RevByte(t);
  }
  if (c & 1)
    b[c / 2] = RevByte(b[c / 2]);
}

int main(void)
{
  int i;
  unsigned char buf[16] = 
  {
    0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
    0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
  };

  RevBytes(buf, 16);

  for (i = 0; i < 16; i++)
    printf("0x%02X ", buf[i]);
  puts("");

  return 0;
}

出力(ideone):

0xF0 0xE0 0xD0 0xC0 0xB0 0xA0 0x90 0x80 0x70 0x60 0x50 0x40 0x30 0x20 0x10 0x00
于 2013-02-25T04:43:32.693 に答える
0

これを行うには、ビット反転方法が正しいと仮定して、ストレージに余分なスペースを確保できる場合charは、バイトをトラバースするだけです。次の方法を検討してください。

static void swapReverseBytes(char* arr, size_t len)
{
  int i = 0;
  char tmp = 0;
  if(arr == NULL || len < 1)
    return;
  if(len == 1) {
    arr[0] = reverseByte(arr[0]);
    return;
  }
  for(i = 0 ; i < (len / 2) ; ++i) {
    tmp = arr[len - i - 1];
    arr[len - i - 1] = reverseByte(arr[i]);
    arr[i] = reverseByte(tmp);
  }
}

これは大まかなスケッチであり(コンパイルする必要があると思います)、1つずつエラーがないと仮定すると、これは機能するはずです。前述のように、を使用してビットを反転するのがおそらく最速LUTですが、配列の走査順序に関する状態を維持しない限り、実際に各バイトを移動する必要があるため、バイトスワッピング方法は比較的似ています。その場合、ある状態(つまりフラグ)を使用して、配列を正常にトラバースするか(1...n)、逆の順序でトラバースするか()を決定することは非常に可能n...1です。いずれにせよ、Big-Oではスワッピングは「無料」ですが、実際に(必ずしも)パフォーマンスに影響を与える可能性があります。したがって、最適化が本当に速度と余分なものである場合int宇宙ではそれほど多くはありませんが、この状態はあなたにとって価値があるかもしれません。このトリックは、これが内部的な場合にのみ機能することに注意してください。このメソッドがユーザーに公開されていて、ユーザーがフラグについて知らない場合、これは実際には何も反転しません。これを使用する別のオプションは、を使用できる場合C++、ユーザーのためにこの機能をカプセル化するクラスを作成できることです。

于 2013-02-25T04:44:17.820 に答える
0

これを行うには、ビット反転方法が正しいと仮定して、ストレージに余分なスペースを確保できる場合charは、バイトをトラバースするだけです。次の方法を検討してください。

static void swapReverseBytes(char* arr, size_t len)
{
  int i = 0;
  char tmp = 0;
  if(arr == NULL || len < 1)
    return;
  if(len == 1) {
    arr[0] = reverseByte(arr[0]);
    return;
  }
  for(i = 0 ; i < (len / 2) ; ++i) {
    tmp = arr[len - i - 1];
    arr[len - i - 1] = reverseByte(arr[i]);
    arr[i] = reverseByte(tmp);
  }
}

これは大まかなスケッチであり(コンパイルする必要があると思います)、1つずつエラーがないと仮定すると、これは機能するはずです。前述のように、を使用してビットを反転するのがおそらく最速LUTですが、配列の走査順序に関する状態を維持しない限り、実際に各バイトを移動する必要があるため、バイトスワッピングは比較的似ています。その場合、ある状態(つまりフラグ)を使用して、配列を正常にトラバースするか(1...n)、逆の順序でトラバースするか()を決定することは非常に可能n...1です。いずれにせよ、Big-Oではスワッピングは「無料」ですが、実際に(必ずしもそうとは限りません)パフォーマンスへの影響を示します(バイト順序の「実際の」スワッピングがないため)。C++これは、ユーザーが並べ替えられた配列を期待している場合は機能しないことに注意してください。このトリックは、これが内部である場合(または、クラスのように何らかのカプセル化がある場合)にのみ機能します。

于 2013-02-25T04:47:41.123 に答える
0

コレクションの要素を逆にするのは古いトリックです。最初と最後を入れ替え、次にfirst + 1とlast-1を入れ替え、次に... first+iがlast-jと同じかそれ以上になるまでコレクションを入れ替えます。

あなたがそれに追加しなければならないのは

-それらを交換する前に2つのエントリのビットを反転します

-中央に要素が1つ残っている場合は、その場でビットを反転します

于 2013-02-25T04:32:59.657 に答える