目标c中的adler32校验和

use*_*097 0 iphone objective-c adler32 ios

我正在开发一个应用程序,它使用用户位置信息向服务器发送数据.服务器接受基于校验和计算的数据,这是用java编写的.
这是用Java编写的代码:

private static final String CHECKSUM_CONS = "1217278743473774374";
private static String createChecksum(double lat, double lon) {

    int latLon = (int) ((lat + lon) * 1E6);
    String checkSumStr = CHECKSUM_CONS + latLon;
    byte buffer[] = checkSumStr.getBytes();
    ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
    CheckedInputStream cis = new CheckedInputStream(bais, new Adler32());
    byte readBuffer[] = new byte[50];
    long value = 0;
    try {
        while (cis.read(readBuffer) >= 0) {
            value = cis.getChecksum().getValue();
        }
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, e.getMessage(), e);
    }
    return String.valueOf(value);
}
Run Code Online (Sandbox Code Playgroud)

我试图寻求帮助,以找出如何写出与此相当的客观c.以上功能使用adler32,我对此没有任何线索.请帮忙.

谢谢你的时间.

Mar*_*ler 8

@achievelimitless和@ user3275​​097显示的答案不正确.

首先,不应使用带符号的整数.负数的模运算符在不同语言中的定义不同,应尽可能避免使用.只需使用无符号整数即可.

其次,循环将快速溢出16位累加器,这将给出错误的答案.模数运算可以延迟,但必须在溢出之前完成.您可以通过假设所有输入字节都是255来计算可以安全执行的循环数.

第三,由于第二点,你不应该使用16位类型.您应该使用至少32位类型,以避免经常进行模数运算.您仍然需要限制循环次数,但数量会变得更大.对于32位无符号类型,最大循环数为5552.因此基本代码如下所示:

#define MOD 65521
#define MAX 5552

unsigned long adler32(unsigned char *buf, size_t len)
{
    unsigned long a = 1, b = 0;
    size_t n;

    while (len) {
        n = len > MAX ? MAX : len;
        len -= n;
        do {
            a += *buf++;
            b += a;
        } while (--n);
        a %= MOD;
        b %= MOD;
    }
    return a | (b << 16);
}
Run Code Online (Sandbox Code Playgroud)

如@Sulthan所述,您应该只使用adler32()zlib中提供的功能,该功能已经存在于Mac OS X和iOS上.

  • 我给你+1,因为......好吧,是你.但是,没有理由实现该算法,因为zlib库在iOS上具有所有功能,包括`adler32`. (3认同)