2012-03-26 77 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