web-dev-qa-db-ja.com

Javaで符号なしバイトのビットを反転するにはどうすればよいですか?

非常に単純なタイプの暗号化用のデコーダーを作成しようとしています。 0〜255の数字はスキャナーを介して入力され、ビットが反転されてから文字に変換されて印刷されます。

たとえば、178という数字は「M」という文字に変換する必要があります。

178は10110010です。

すべてのビットを反転すると、文字として77または「M」である01001101が得られます。

私が抱えている主な問題は、私が知る限り、Javaは符号なしバイトをサポートしていません。値をintまたはshortとして読み取ることができますが、その間、値はオフになります。余分なビットによる変換。理想的にはビット単位の補数演算子を使用できますが、符号付き数値を使用してこれを行うと、負の値になると思います。これにどのようにアプローチするかについてのアイデアはありますか?

16
DavidKelly999

私は単に1の補数を使用し、バイナリとを使用して他のビットを取り除きます。

public class Conv {
    public static void main(String[] args) {
        int val = 178;
        val = ~val & 0xff;
        System.out.println((char) val);
    }
}
14
stacker
_~n & 0xff
_

_~_は補数を実行し、すべての数値演算と同様に暗黙的に整数に変換します。次に、_& 0xff_は、下位8ビットを除くすべてをマスクして、符号なしの値を再び整数として取得します。

私は最初にあなたの質問を別の方法で読み、ビットの値の代わりに順序を逆にしました、そしてこれが答えでした。

Integer.reverse() (未テスト)を使用できます:

_Integer.reverse(n << 24) & 0xff
_
11
starblue

Javaのビット演算はintに対して定義されているため、intではなくbyteを使用するのが理にかなっています。 Scanner.nextInt ではなく Scanner.nextByte 。ユーザーの入力を検証して、入力されたすべての整数が0〜255の範囲にあることを確認し、範囲外の数値が検出された場合は適切なエラーメッセージを表示する必要があります。

数値を整数に格納したら、最下位8ビットを反転することができますXOR with 0xff。これは、0から255までのすべての入力で期待どおりに機能するはずです。

x ^= 0xff;

例:

String input = "178 0 255";
Scanner s = new Scanner(input);
while (s.hasNextInt()) {
    int x = s.nextInt();
    if (x < 0 || x > 255) {
        System.err.println("Not in range 0-255: " + x);
    } else {
        x ^= 0xff;
        System.out.println(x);
    }
}

結果:

77
255
0
6
Mark Byers

Javaがこれをサポートしている場合は、それをより大きな型に読み取り、ビット単位で補完してから、不要なビットをビットマスクすることができます。

int x = [your byte];
x = ~x & 0xFF;
private byte reverseBitsByte(byte x)
{
    int intSize = 8;

    byte y = 0;
    for (int position = intSize - 1; position >= 0; position--)
    {
        y += ((x & 1) << position);
        x >>= 1;
    }
    return y;
}
0
Xkynar

これを行う最も簡単な方法は、次の3つの段階です。

  1. 値をint(Javaでは32ビット)として読み取ります。ネガティブと読めるかもしれませんが、とにかく下の8ビットしか気にしません。 int i = scanner.nextByte();
  2. ビット単位の演算子を使用してintとして反転を実行します(あなたが言うように、上位ビットとして1を与えます:i = ~i;
  3. 論理積で上位ビットを失います:i = i & 0xFF;

次に、結果を文字として使用します(Javaでは実際には16ビットですが、8ビットのみを使用します)。

char c=(char)a;
System.out.println(c); 

すべて一緒に:

int i = scanner.nextByte(); // change this to nextInt() depending on file format
i = ~i;
i = i & 0xFF;
char c=(char)a;
System.out.println(c); 
0
Nick Fortescue