Контрольная сумма adler32 в цели c

Я работаю над приложением, которое отправляет данные на сервер с информацией о местоположении пользователя. Сервер принимает эти данные на основе вычисления контрольной суммы, которая написана на языке 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);
}

Я пытался искать помощь, чтобы узнать, как написать объективный эквивалент этого. Выше функция использует adler32, и я понятия не имею об этом. Пожалуйста помоги.

Спасибо за ваше время.

2 ответа

Решение

На основании определения контрольной суммы adler32, как упомянуто в Википедии,

Реализация цели 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");

Пожалуйста, дайте мне знать, если нужно больше информации

Ответы, показанные здесь @achievelimitless и @user3275097, неверны.

Во-первых, целые числа со знаком не должны использоваться. Оператор по модулю отрицательных чисел определяется по-разному на разных языках, и его следует избегать, когда это возможно. Вместо этого просто используйте целые числа без знака.

Во-вторых, шлейфы быстро переполнят 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, вы должны просто использовать adler32() Функция предусмотрена в zlib, который уже есть на Mac OS X и iOS.

Другие вопросы по тегам