如何计算二进制校验和?

时间:2012-07-24 21:17:25

标签: ios checksum

我正在处理我发送的硬件通信应用程序或需要来自外部硬件的数据。我已完成需求数据部分。

我发现我可以使用一些帮助来计算校验和。

将包创建为NSMutableData,然后在发送之前将其转换为字节数组。 包看起来像这样:

0x1E 0x2D 0x2F DATA校验和

我想我可以将十六进制转换为二进制来逐个计算它们。但我不知道这是不是一个好主意。如果这是唯一的方法,请告诉我,或者有一些我不知道的内置函数。 任何建议将不胜感激。

顺便说一下,我刚从其他帖子中找到了C#的代码,我会尝试让它在我的应用程序中运行。如果可以,我会与你分享。仍然会有任何建议。

package org.example.checksum;

public class InternetChecksum {

  /**
   * Calculate the Internet Checksum of a buffer (RFC 1071 -     http://www.faqs.org/rfcs/rfc1071.html)
   * Algorithm is
   * 1) apply a 16-bit 1's complement sum over all octets (adjacent 8-bit pairs [A,B], final odd length is [A,0])
   * 2) apply 1's complement to this final sum
   *
   * Notes:
   * 1's complement is bitwise NOT of positive value.
   * Ensure that any carry bits are added back to avoid off-by-one errors
   *
   *
   * @param buf The message
   * @return The checksum
   */
  public long calculateChecksum(byte[] buf) {
int length = buf.length;
int i = 0;

long sum = 0;
long data;

// Handle all pairs
while (length > 1) {
  // Corrected to include @Andy's edits and various comments on Stack Overflow
  data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF));
  sum += data;
  // 1's complement carry bit correction in 16-bits (detecting sign extension)
  if ((sum & 0xFFFF0000) > 0) {
    sum = sum & 0xFFFF;
    sum += 1;
  }

  i += 2;
  length -= 2;
}

// Handle remaining byte in odd length buffers
if (length > 0) {
  // Corrected to include @Andy's edits and various comments on Stack Overflow
  sum += (buf[i] << 8 & 0xFF00);
  // 1's complement carry bit correction in 16-bits (detecting sign extension)
  if ((sum & 0xFFFF0000) > 0) {
    sum = sum & 0xFFFF;
    sum += 1;
  }
}

// Final 1's complement value correction to 16-bits
sum = ~sum;
sum = sum & 0xFFFF;
return sum;

  }

}

1 个答案:

答案 0 :(得分:1)

当我在一年前发布这个问题时,我对Objective-C还是一个新手。结果证明这很容易。

计算校验和的方式取决于通信协议中如何定义校验和。在我的例子中,校验和只是发送的所有先前字节或要发送的数据的总和。

所以如果我有一个有五个字节的NSMutableData * cmd:

0x10 0x14 0xE1 0xA4 0x32

校验和是0x10 + 0x14 + 0xE1 + 0xA4 + 0x32

的最后一个字节

因此总和为01DB,校验和为0xDB。

代码:

//i is the length of cmd
- (Byte)CalcCheckSum:(Byte)i data:(NSMutableData *)cmd
{   Byte * cmdByte = (Byte *)malloc(i);
    memcpy(cmdByte, [cmd bytes], i);
    Byte local_cs = 0;
    int j = 0;
    while (i>0) {
        local_cs += cmdByte[j];
        i--;
        j++;
    };
    local_cs = local_cs&0xff;
    return local_cs;
}

使用它:

Byte checkSum = [self CalcCheckSum:[command length] data:command];

希望它有所帮助。