首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标c中的adler32校验和

目标c中的adler32校验和
EN

Stack Overflow用户
提问于 2014-02-05 17:42:16
回答 2查看 1.3K关注 0票数 0

我正在开发一个应用程序,它用用户位置信息将数据发送到服务器。服务器基于校验和计算接受此数据,该校验和计算是用java编写的。

下面是用Java编写的代码:

代码语言:javascript
复制
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);
}

我试着寻求帮助,以找出如何写目标c等价于此。上面的函数使用adler32,我对此一无所知。请帮帮忙。

耽误您时间,实在对不起。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-05 18:02:45

在adler32校验和定义的基础上,如维基百科中所述,

目标C的执行情况如下:

代码语言:javascript
复制
   static NSNumber * adlerChecksumof(NSString *str)
{
    NSMutableData *data= [[NSMutableData alloc]init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    for (int i = 0; i < ([str length] / 2); i++)
    {
        byte_chars[0] = [str characterAtIndex:i*2];
        byte_chars[1] = [str characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
    }

    int16_t a=1;
    int16_t b=0;
    Byte * dataBytes= (Byte *)[data bytes];
    for (int i=0; i<[data length]; i++)
    {
        a+= dataBytes[i];
        b+=a;
    }

    a%= 65521;
    b%= 65521;

    int32_t adlerChecksum= b*65536+a;
    return @(adlerChecksum);
}

在这里,str将是您在问题中提到的字符串。

因此,当您想要计算某些字符串的校验和时,只需执行以下操作:

代码语言:javascript
复制
NSNumber * calculatedChkSm= adlerChecksumof(@"1217278743473774374");

如果需要更多的信息,请告诉我

票数 0
EN

Stack Overflow用户

发布于 2014-02-07 17:58:39

@achievelimitless和@ here 3275097给出的答案是不正确的。

首先,不应使用有符号整数。负数上的模运算符在不同的语言中有不同的定义,在可能的情况下应该避免。只需使用无符号整数。

第二,循环将迅速溢出16位累加器,这将给出错误的答案。模块操作可以推迟,但必须在溢出之前完成。您可以通过假设所有输入字节都是255来计算可以安全地执行多少个循环。

第三,由于第二点,您不应该使用16位类型.您应该至少使用32位类型,以避免经常进行模块化操作。你仍然需要限制循环的数量,但是循环的数量会大得多。对于32位无符号类型,循环的最大数目是5552.因此,基本代码如下:

代码语言:javascript
复制
#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);
}

正如@Sulthan所指出的,您应该简单地使用zlib中提供的adler32()函数,它已经存在于Mac和iOS上。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21584517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档