2012-03-26 64 views
2

我正在下面的代码从C#转换为Java时:签名/未签名的情况下C#转换为Java

public static byte MakeCS(byte[] arr) 
    { 
     byte cs = 0; 
     for (int i = 0; i < arr.Length; i++) 
     { 
      cs += arr[i]; 
     } 
     return cs; 
    } 

我幼稚的对话是刚刚改变arr.Length到arr.length; )

但是,这给了我不正确的校验和,因为java已经签署了字节,并且c#有未签名的(我试着将c#代码改为sbyte并且工作正常)。

处理这种情况的正确方法是什么?我知道我可以通过0xFF将Java字节“转换”为无符号位,但我不确定在哪里执行此操作!

谢谢!

回答

2

你只需要改变返回值,并返回类型int

return cs & 0xFF; 

你并不需要更改CS的类型,因为它会产生相同的结果无论是其一个intshort或使用0xFF后的long。你也不需要掩盖每个值。

public static void main(String... args) { 
    byte[] bytes = { 1, -128, -1 }; // check sum is -128 or 0x80 or 128 (unsigned) 
    System.out.println("makeCS "+ makeCS(bytes)); 
    System.out.println("makeCS2 "+ makeCS2(bytes)); 
    System.out.println("makeCS3 "+ makeCS3(bytes)); 
} 

public static int makeCS(byte... arr) { 
    byte cs = 0; 
    for (byte b : arr) 
     cs += b; 
    return cs & 0xFF; 
} 

public static int makeCS2(byte[] arr) 
{ 
    int cs = 0; 
    for (int i = 0; i < arr.length; i++) 
    { 
     int add = arr[i]; 
     cs += (0xFF & add); 
     cs &= 0xFF; 
    } 
    return cs; 
} 

public static short makeCS3(byte[] arr) 
{ 
    short cs = 0; 
    for (int i = 0; i < arr.length; i++) 
    { 
     cs += arr[i]; 
    } 
    return cs; 
} 

打印

makeCS 128 
makeCS2 128 
makeCS3 -128 
+0

+1为了达到比我的回答更好的地步。尽管如此,为了澄清OP:基本上,有符号和无符号字节之间唯一不同的代码是使用'<=', '> =','<', '>','/','%'或'toString'的代码。 – 2012-03-26 16:05:06

+0

对于'<=' '> =''<' and '>'您可以添加'Byte.MIN_VALUE'或'&0xFF'其余的您需要'&0xFF'添加MIN_VALUE技巧对'long'很有用,因为没有更大的类型投到(BigInteger除外) – 2012-03-26 16:09:22

+0

有些人更喜欢XOR或减法而不是加法,但它们都是等价的。(就我个人而言,我更容易理解'^'发生了什么,只是因为我不必通过溢出来推理。) – 2012-03-26 16:17:33

1

试试这个:

public static byte MakeCS(byte[] arr) 
{ 
    int cs = 0; 
    for (int i = 0; i < arr.Length; i++) 
    { 
     int add = arr[i]; 
     cs += (0xFF & add); 
     cs &= 0xFF; 
    } 
    return cs; 
} 

这将其添加到CS之前截断int的标志部分,10再次截断一切都会过去八的位模仿的无符号加法。

+0

这是没有必要的。 – 2012-03-26 15:39:22

+0

@LouisWasserman也许这不是处理这个问题的最有效方式,但我认为只要它有效,这是一个合理的转换。我怀疑这里的效率是非常值得关注的(除非OP另有说明)。 – dasblinkenlight 2012-03-26 15:43:28

+0

对不起,我的意思是说,OP的代码_asd已正常工作。这只是使用OP方法的代码必须改变其行为。 – 2012-03-26 15:44:55

0

这听起来像你期待使用c#byte的整个8位来完成总和。为了正确地移植到Java,您需要选择一个至少具有相同精度的类型。 Java中最接近的类型是short

public static short MakeCS(byte[] arr) 
{ 
    short cs = 0; 
    for (int i = 0; i < arr.length; i++) 
    { 
     cs += arr[i]; 
    } 
    return cs; 
} 

注意:虽然这不是一个完美的端口。它打开了C#中溢出的代码不会在Java版本中溢出的可能性,因为Java short具有更高的精度,即C#byte