Java 反转超过最大字节大小的位移位的问题?

Java 反转超过最大字节大小的位移位的问题?,java,type-conversion,Java,Type Conversion,我试图在二进制字符串上做一个简单的凯撒移位,它需要是可逆的。我是用这种方法做的 public static String cShift(String ptxt, int addFactor) { String ascii = ""; for (int i = 0; i < ptxt.length(); i+=8) { int character = Integer.parseInt(ptxt.substring

我试图在二进制字符串上做一个简单的凯撒移位,它需要是可逆的。我是用这种方法做的

public static String cShift(String ptxt, int addFactor)
    {
        String ascii = "";
        for (int i = 0; i < ptxt.length(); i+=8)
        {
            int character = Integer.parseInt(ptxt.substring(i, i+8), 2);
            byte sum = (byte) (character + addFactor);
            ascii += (char)sum;
        }
        String returnToBinary = convertToBinary(ascii);
        return returnToBinary;
    }
当我以12的C档运行此程序,然后以-12的C档进行倒车时,我得到这个

01110100011001010111001101110100001000010011001000110010010001100010101000100000
111111111000000001110001011111111111111110000000001011010011111000111110010100100011011000101100
ÿ?qÿ?->>R6,
ÿótesÿót!22F*
第一个字符串只是将测试字符串转换为二进制。第二个字符串是二进制cShift的结果。第三个字符串是将其转换为ascii的结果,第四个字符串是在CSShift上使用-12反转并转换为ascii的结果


我很清楚,在翻滚过程中不知何故会增加额外的部分,我不完全确定如何应对。谢谢。

当扩展到
字符时,需要屏蔽
字节
,否则符号位将被扩展

ascii += (char)(sum & 0xFF)
如果不需要符号扩展名,则在加宽有符号数字类型时应用此遮罩模式

anInt = aByte & 0xFF;
anInt = aShort & 0xFFFF;
aLong = anInt & 0xFFFFFFFFL; // notice the L

下面是一个例子来说明:

byte b = -1; // 0xFF
char ch = (char) b; // 0xFFFF
int i = ch;
System.out.println(i); // prints "65535", which is 0xFFFF

byte b = -1; // 0xFF
char ch = (char) (b & 0xFF); // 0xFF
int i = ch;
System.out.println(i); // prints "255", which is 0xFF

这里有一个教训。如果你读过的话,你会看到一些围绕着标志延伸箍的东西。这本书中的谜题与我上面的谜题基本相同,但可能更令人困惑:

// Java Puzzlers, Puzzle 6: Multicast
System.out.println((int) (char) (byte) -1); // prints 65535
有两种方法可以解决这一问题:

  • 避免使用
    byte
    short
    。你很少需要这样做
  • 如果你和他们一起工作,要时刻提防掩饰的需要
  • byte
    char
    总是很棘手,因为:
    • 虽然
      char
      byte
    • char
      无符号,而
      byte
      无符号
    • 因此,这不是一个简单的加宽转换,而是一个加宽-缩小转换
以下转换结合了加宽和缩小基本体转换:

  • 字节
    字符
首先,通过扩大原语转换将
字节
转换为
int
,然后通过缩小原语转换将得到的
int
转换为
char


其他参考资料

什么是二进制字符串?我想我看不出
“test!22*F”
是如何二进制的。似乎这个问题与OP的另一个问题有关:是的,在这种情况下,这个问题目前是错误的。你不能使用那个测试字符串。这是真的,Terri,你确定你在转换回时正在执行上面的函数吗?我不认为有不同的函数用于转换回;如果他用
N
转换成
cShift
,那么他后来就用
cShift
转换成
-N
。啊-我完全忘记了
char
在Java中是2个字节。接得好。
// Java Puzzlers, Puzzle 6: Multicast
System.out.println((int) (char) (byte) -1); // prints 65535