Domanda

I am working on a app which sends data to server with user location info. Server accept this data based on checksum calculation, which is written in java.
Here is the code written in 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);
}

I tried looking for help to find out how to write objective c equivalent of this. Above function uses adler32 and I don't have any clue about that. Please help.

Thanks for your time.

È stato utile?

Soluzione 2

On basis of definition of adler32 checksum as mentioned in wikipedia,

Objective C implementation would be like this:

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

Here str would be your string as mentioned in your question..

So when you want to calculate checksum of some string just do this:

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

Please Let me know if more info needed

Altri suggerimenti

The answers shown here by @achievelimitless and @user3275097 are incorrect.

First off, signed integers should not be used. The modulo operator on negative numbers is defined differently in different languages, and should be avoided when possible. Simply use unsigned integers instead.

Second, the loops will quickly overflow the 16-bit accumulators, which will give the wrong answer. The modulo operations can be deferred, but they must be done before overflow. You can calculate how many loops you can do safely by assuming that all of the input bytes are 255.

Third, because of the second point, you should not use 16-bit types. You should use at least 32-bit types to avoid having to do the modulo operation very often. You still need to limit the number of loops, but the number gets much bigger. For 32-bit unsigned types, the maximum number of loops is 5552. So the basic code looks like:

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

As noted by @Sulthan, you should simply use the adler32() function provided in zlib, which is already there on Mac OS X and iOS.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top