Java 从int到byte的有损转换?
我的简单加密算法我正在做的一个练习是给我一个从int到byte的可能的有损转换?但是我不知道为什么它会给我这个错误有什么想法吗Java 从int到byte的有损转换?,java,encryption,Java,Encryption,我的简单加密算法我正在做的一个练习是给我一个从int到byte的可能的有损转换?但是我不知道为什么它会给我这个错误有什么想法吗 public class Rot13Crypt extends CryptStream { public Rot13Crypt(StreamPair theStreams) { super(theStreams); } protected byte [] cryptData(byte [] data, int len)
public class Rot13Crypt extends CryptStream
{
public Rot13Crypt(StreamPair theStreams)
{
super(theStreams);
}
protected byte [] cryptData(byte [] data, int len)
{
byte [] cryptedByte = new byte[len];
for(int i = 0; i < len; i++)
{
cryptedByte[i] = (data[i] + 13) % 256;
}
return cryptedByte;
}
protected byte [] decryptData(byte [] data, int len)
{
byte [] decryptedByte = new byte[len];
for(int i = 0; i < len; i++)
{
decryptedByte[i] = (data[i] * 256) - 13;
}
return decryptedByte;
}
}
public类Rot13Crypt扩展了CryptStream
{
公共ROT13密码(流对流)
{
超级(theStreams);
}
受保护的字节[]加密数据(字节[]数据,整数长度)
{
byte[]cryptedByte=新字节[len];
对于(int i=0;i
一个字节有2^8=256个唯一状态,因此它能代表的最大范围是-128到127
所以假设
decryptedByte[i] = (data[i] * 256) - 13;
data[i]
值大于1
将导致该值溢出一个字节的最大值字节大小为8位,整数大小为32位。因此,执行此转换可能会丢失一些信息 字节数据类型是一个8位有符号2的补码整数。
int数据类型是一个32位有符号2的补码整数
无法将整数放入字节。因此,在精度上的损失。
我希望这是清楚的
示例引用是它给出了错误消息,因为您试图将int值表达式的值赋给
字节
。这是一个潜在的有损操作:凭直觉,您无法将所有可能的int
值放入字节中
Java语言要求在将int值表达式赋给字节时使用(byte)
强制转换
您可以在两个地方执行此操作:
cryptedByte[i] = (data[i] + 13) % 256;
decryptedByte[i] = (data[i] * 256) - 13;
在第一个表达式中,表达式的值在0到255之间。。。但是Javabyte
值在-128到+127之间
在第二个表达式中,表达式值可能具有范围(-128*256)-13
到`(+127*256)-13的值。那显然不合适
但这实际上是毫无意义的。Java不允许上述代码的变体,即使您(一个聪明人)可以证明表达式的范围将“适合”到字节中。JLS禁止这样做。(Java编译器不必是一般定理证明者!!)
只有在表达式是编译时常量表达式且表达式的实际值在byte
范围内时,才可以将int值表达式分配给byte
而不进行类型转换
如果您感兴趣,请指定以下状态:
此外,如果表达式是byte、short、char或int类型的常量表达式(§15.28):
- 如果变量的类型是byte、short或char,并且常量表达式的值可以在变量的类型中表示,则可以使用窄化原语转换
(您需要通过“常量表达式”和“缩小原语转换”来了解规范的含义。我将留给感兴趣的人自己去做。)
那么我会在13和256之前添加一个(字节)强制转换吗
没有。你需要投射整个表情;e、 g
cryptedByte[i] = (byte) ((data[i] + 13) % 256);
在Java中,int
类型使用32位编码,byte
类型使用8位编码。如果将int
转换为字节
,如果原始值大于127或小于-128,则可能会丢失信息
整数文本默认为int
,对int
的操作返回int
。因此,data[i]+13
的结果是int
;(数据[i]+13)%256也一样。当您尝试将该结果存储到字节(此处为cryptedByte[i])中时,Java会警告您“可能的有损转换”。您在此处遇到问题
cryptedByte[i] = (data[i] + 13) % 256;
这里呢
decryptedByte[i] = (data[i] * 256) - 13;
256
和13
是int
类型的文本。当您使用它们和占用较少内存的类型(在本例中为byte
)执行操作时,会发生类型升级:数据[i]
被隐式转换(升级)为类型int
。因此,这两个表达式的计算结果都是int
。你知道当你把一个int转换成一个字节时会发生什么,对吗?您可能会丢失数据。这是因为字节
的内存限制小于int
当每个字节位于一个变量内时,您只需在分配每个字节时进行转换,因此java可以确保所有字节都在-127和127之间,这是ascii范围。以下措施应该有效:
public class Rot13Crypt extends CryptStream
{
public Rot13Crypt(StreamPair theStreams)
{
super(theStreams);
}
protected byte [] cryptData(byte [] data, int len)
{
byte [] cryptedByte = new byte[len];
for(int i = 0; i < len; i++)
{
cryptedByte[i] = (byte) (data[i] + 13) % 256;
}
return cryptedByte;
}
protected byte [] decryptData(byte [] data, int len)
{
byte [] decryptedByte = new byte[len];
for(int i = 0; i < len; i++)
{
decryptedByte[i] = (byte) (data[i] * 256) - 13;
}
return decryptedByte;
}
public类Rot13Crypt扩展了CryptStream
{
公共ROT13密码(流对流)
{
超级(theStreams);
}
受保护的字节[]加密数据(字节[]数据,整数长度)
{
byte[]cryptedByte=新字节[len];
对于(int i=0;i
}请提供完整的编译错误消息/消息,包括行号。字节在Java中是有符号的-它可以包含-128和127之间的数字,而不是255。那么我是否要在13和256之前添加一个(字节)强制转换?不,只需将整个结果强制转换为byte:cryptedByte[i]=(byte)((数据[i]+13)%256);非常感谢你!现在我很感激你的帮助!非常感谢你!一开始我想不出来