计算校验和 return android 中的错误值
Calculate checksum return wrong value in android
您好,我正在将 c# 应用程序转换为 android 并且正在从字节数组计算校验和,与在 c# 中一样。但是它 return 字节数组下面的错误值。任何人都请帮助 this.Thank 你。
C# 字节数组:
[41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132]
c#代码:
public static uint CalculateChecksum(byte[] buffer, int offset, int length)
{
uint cs = 0;
for (int i = offset; i < offset + length & i < buffer.Length; i += 2)
{
ushort s = BitConverter.ToUInt16(buffer, i);
cs += s;
}
return cs;
}
value getting 4736620 将此值转换为字节数组得到 [108,70,72,0]
Android字节数组
[41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124]
Android代码:
public static long checkSum(byte[] buffer, int offset, int length) {
long cs = 0;
for (int i = offset; i < offset + length & i < buffer.length; i += 2) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buffer[i]);
bb.put(buffer[i+1]);
long shortVal = bb.getShort(0);
cs += shortVal;
}
return cs;
}
value getting -4438420 将此值转换为字节数组
ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt((int) value).array();
给出 [108,70,-68,-1]
哪里做错了?为什么它的 return 不同的值?
请帮我。谢谢。
字节数组的内容不同(例如,C# 中的第二个位置与 Android 中的不同)。所以从我的角度来看,代码 returns 不同的校验和是可以的。
编辑:数组的内容确实不同。一个由有符号字节组成,另一个由无符号字节组成。这是一个差异(即使位表示可能相同)并且与大端与小端无关。您面临的问题是因为在 Java 版本中,您再次使用带符号的短裤,而 C# 版本使用无符号短裤。在那里,符号使计算错误的一项是 2^16 的倍数。事实上,如果您在 C# 中使用 signed int16,您也会得到与 Android 解决方案相同的结果。
因此,简单的解决方案是从字节缓冲区请求一个整数,而不是短整数,因为后者是有符号的。或者,您可以添加 2^16 以防短路为负(ushort 永远不可能):
public static long checkSum(byte[] buffer, int offset, int length) {
long cs = 0;
for (int i = offset; i < offset + length & i < buffer.length; i += 2) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buffer[i]);
bb.put(buffer[i+1]);
long shortVal = bb.getShort(0);
if (shortVal < 0) { shortVal += (1 << 16); }
cs += shortVal;
}
return cs;
}
您好,我正在将 c# 应用程序转换为 android 并且正在从字节数组计算校验和,与在 c# 中一样。但是它 return 字节数组下面的错误值。任何人都请帮助 this.Thank 你。
C# 字节数组:
[41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132, 41, 132]
c#代码:
public static uint CalculateChecksum(byte[] buffer, int offset, int length)
{
uint cs = 0;
for (int i = offset; i < offset + length & i < buffer.Length; i += 2)
{
ushort s = BitConverter.ToUInt16(buffer, i);
cs += s;
}
return cs;
}
value getting 4736620 将此值转换为字节数组得到 [108,70,72,0]
Android字节数组
[41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124 , 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124, 41, -124]
Android代码:
public static long checkSum(byte[] buffer, int offset, int length) {
long cs = 0;
for (int i = offset; i < offset + length & i < buffer.length; i += 2) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buffer[i]);
bb.put(buffer[i+1]);
long shortVal = bb.getShort(0);
cs += shortVal;
}
return cs;
}
value getting -4438420 将此值转换为字节数组
ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt((int) value).array();
给出 [108,70,-68,-1]
哪里做错了?为什么它的 return 不同的值? 请帮我。谢谢。
字节数组的内容不同(例如,C# 中的第二个位置与 Android 中的不同)。所以从我的角度来看,代码 returns 不同的校验和是可以的。
编辑:数组的内容确实不同。一个由有符号字节组成,另一个由无符号字节组成。这是一个差异(即使位表示可能相同)并且与大端与小端无关。您面临的问题是因为在 Java 版本中,您再次使用带符号的短裤,而 C# 版本使用无符号短裤。在那里,符号使计算错误的一项是 2^16 的倍数。事实上,如果您在 C# 中使用 signed int16,您也会得到与 Android 解决方案相同的结果。
因此,简单的解决方案是从字节缓冲区请求一个整数,而不是短整数,因为后者是有符号的。或者,您可以添加 2^16 以防短路为负(ushort 永远不可能):
public static long checkSum(byte[] buffer, int offset, int length) {
long cs = 0;
for (int i = offset; i < offset + length & i < buffer.length; i += 2) {
ByteBuffer bb = ByteBuffer.allocate(2);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buffer[i]);
bb.put(buffer[i+1]);
long shortVal = bb.getShort(0);
if (shortVal < 0) { shortVal += (1 << 16); }
cs += shortVal;
}
return cs;
}