非常に単純なタイプの暗号化用のデコーダーを作成しようとしています。 0〜255の数字はスキャナーを介して入力され、ビットが反転されてから文字に変換されて印刷されます。
たとえば、178という数字は「M」という文字に変換する必要があります。
178は10110010です。
すべてのビットを反転すると、文字として77または「M」である01001101が得られます。
私が抱えている主な問題は、私が知る限り、Javaは符号なしバイトをサポートしていません。値をintまたはshortとして読み取ることができますが、その間、値はオフになります。余分なビットによる変換。理想的にはビット単位の補数演算子を使用できますが、符号付き数値を使用してこれを行うと、負の値になると思います。これにどのようにアプローチするかについてのアイデアはありますか?
私は単に1の補数を使用し、バイナリとを使用して他のビットを取り除きます。
public class Conv {
public static void main(String[] args) {
int val = 178;
val = ~val & 0xff;
System.out.println((char) val);
}
}
_~n & 0xff
_
_~
_は補数を実行し、すべての数値演算と同様に暗黙的に整数に変換します。次に、_& 0xff
_は、下位8ビットを除くすべてをマスクして、符号なしの値を再び整数として取得します。
私は最初にあなたの質問を別の方法で読み、ビットの値の代わりに順序を逆にしました、そしてこれが答えでした。
Integer.reverse()
(未テスト)を使用できます:
_Integer.reverse(n << 24) & 0xff
_
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
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;
}
これを行う最も簡単な方法は、次の3つの段階です。
int i = scanner.nextByte();
i = ~i;
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);