2014-02-05 44 views
0

我正在使用用户位置信息发送数据到服务器的应用程序。服务器接受基于校验和计算的数据,这是用java编写的。
这里是用Java编写代码:adler32校验和在目标c

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,我对此没有任何线索。请帮忙。

谢谢你的时间。

+0

快速谷歌的研究给了我[Java源(http://developer.classpath.org/doc/java/util/zip/Adler32-source.html)以及一个[NSData的类别(HTTPS: //github.com/nicerobot/objc/tree/master/NSData/NSData%2BAdler32)。两者都应该有所帮助。 – Volker

回答

-1

wikipedia提到Adler32校验的定义的基础上,

Objective C的实现是这样的:在你的问题中提到

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将是你的字符串..

所以当你想计算一些字符串的校验和只是这样做:

NSNumber * calculatedChkSm= adlerChecksumof(@"1217278743473774374"); 

请让我知道是否需要更多信息

+1

如果未使用ARC,则必须在返回校验和之前释放NSData。 – Volker

+0

感谢和对我迟到的回应感到抱歉。我现在要试一下,很快就会回复。 – user3275097

+0

@Volker,我试着使用你的代码,但它返回的值与返回的一个java函数不同。对代码进行了一些修改,最后我设法得到了正确的值。下面我发布了更新的代码。谢谢! – user3275097

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); 
} 

正如@Sulthan指出的,你只需要使用zlib的中提供的adler32()功能,这是已经存在在Mac OS X和iOS上。

+3

我给你+1,因为......好吧,就是你。但是,没有理由实现该算法,因为zlib库在iOS中具有其所有功能,包括'adler32'。 – Sulthan