2012-07-24 946 views
1

我正在开发一个我发送或需要外部硬件数据的硬件通信应用程序。我有要求的数据部分完成。如何计算二进制校验和?

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

将包创建为NSMutableData,然后在发送之前将其转换为Byte Array。 一个包看起来是这样的:

0X1E 0x2D值为0x2F数据校验和

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

顺便说一句,我刚刚从其他人的帖子找到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; 

    } 

} 
+0

为什么不使用简单的普通C CRC32? http://www.csbruce.com/~csbruce/software/crc32.c – 2012-07-24 21:41:41

+0

@ H2CO3嗨,你能稍微详细地向我解释一下吗?我试图阅读它,但仍不太清楚如何使用它。谢谢。 – user1491987 2012-07-24 22:27:27

+0

@只需使用名为CalculateCRC32MemoryBuffer的函数 - 其余部分是噪声。 – 2012-07-25 05:25:48

回答

1

当我在一年前发布这个问题时,我对Objective-C仍然很陌生。事实证明,这件事很容易做到。

计算校验和的方式取决于通讯协议中如何定义校验和。在我的情况下,校验和只是所有以前发送的字节或您想要发送的数据的总和。

所以,如果我有一些有5个字节的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]; 

希望它能帮助。

+0

我以其他方式使用校验和:http://stackoverflow.com/questions/19772650/checksum-of-a-hex-string-in-objective-c。你能看看吗? – 2013-11-05 04:24:05