2012-06-08 2 views
2

Я пытаюсь вычислить контрольную сумму CRC для ALAsset. Моя цель - сохранить все CRC и сравнить их позже, чтобы узнать, был ли актив изменен, но каждый раз, когда я генерирую CRC для одного и того же актива, у меня получается другой результат.Расчет контрольной суммы CRC для ALAsset

Для генерации CRC:

#import "CRC32.h" 
#import <zlib.h> 

@implementation CRC32 

+ (uint32_t)CRC32Value:(NSData*)data 
{ 
    uLong crc = crc32(0L, Z_NULL, 0); 
    crc = crc32(crc, [data bytes], [data length]); 
    return crc; 
} 

@end 

Как это используется:

void(^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) 
    {   
    if(result == nil) 
    { 
     return; 
    } 

    CrawlAssetData *assetData = [[CrawlAssetData alloc] init]; 
    [assetData setCrc:[CRC32 CRC32Value:[NSData dataWithBytes:&(result) 
                 length:sizeof(result)]]]; 

Вот мои результаты при генерации CRC в различных случаях для того же актива:

ID: 17575
url: assets-library: //asset/asset.JPG? Id = BB282CBD-F5B1-4771-B48B-E021224C7384 & ext = JPG
размер файла: 1394332
CRC: 3605102491
CreationTime: 2456085,397025

ID: 17826
URL: активы-библиотека: //asset/asset.JPG ID = BB282CBD-F5B1-4771-B48B -E021224C7384 & внутр = JPG
размер файла: 1394332
CRC: 1383370697
CreationTime: 2456085,397025

Как вы можете видеть, файлы и URL-адреса являются одинаковыми, но CRC отличается.

Я исчисляю CRC неправильно? Или я должен использовать другую часть ALAsset для генерации CRC? Возможно, некоторые данные различаются при каждом восстановлении ALAsset?

Заранее благодарен!

ответ

1

Эта линия:

[assetData setCrc:[CRC32 CRC32Value:[NSData dataWithBytes:&(result) 
                length:sizeof(result)]]]; 

... вычисляет CRC в адрес вашего экземпляра ALAsset, а не данные.

Вы можете проверить это путем разделения линии:

NSData *crcData = [NSData dataWithBytes:&(result) 
           length:sizeof(result)]; 
NSLog(@"crcData length: %d", [crcData length]); 
[assetData setCrc:[CRC32 CRC32Value:crcData]]; 

Я думаю, что на выходе вы увидите crcData length: 4.

на основе прослеживания комментария на вопрос спрашивающего (с поправкой) код, чтобы сделать это:

ALAssetRepresentation *rep = [result defaultRepresentation]; 
uint8_t *buffer = malloc(rep.size); 
NSUInteger buffered = [rep getBytes:buffer 
         fromOffset:0 
          length:rep.size 
           error:nil]; 
NSData *data = [NSData dataWithBytesNoCopy:buffer 
            length:buffered 
           freeWhenDone:YES]; 
uint32_t CRC32 = [CRC32 CRC32Value:data]; 
[assetData setCrc:CRC32]; 

В частности, обратите внимание, что sizeof(NSData*) (или NSData *a; sizeof(A)) всегда будет размером указателя (4 на 32-битных системах, таких как iPhone, 8 для 64-разрядной Mac OS X), а не на длину байтовых данных, хранящихся в NSData. Нет нормальной причины, чтобы получить sizeof() указатель NSObject .

+0

спасибо! Какая простая ошибка. Я снова использовал другой код, который использовал адрес, и забыл его вынуть. Здесь была ошибка: '[assetData setCrc: [CRC32 CRC32Value: [NSData dataWithBytes: ([байт данных]) длина: SizeOf (данные)]]],' – jtromo

+1

Окончательное исправление: 'ALAssetRepresentation * респ = [result defaultRepresentation]; Байт * buffer = (Byte *) malloc (rep.size); NSUInteger buffered = [rep getBytes: buffer fromOffset: 0.0 length: rep.size error: nil]; NSData * data = [NSData dataWithBytesNoCopy: длина буфера: буферизированная freeWhenDone: YES]; [assetData setCrc: [CRC32 CRC32Value: [NSData dataWithBytes: ([data bytes]) length: sizeof (data)]]]; ' – jtromo

+0

Я рад, что вы это поняли. Я не знаком с Библиотекой активов, и кажется странным, что это лучший способ получить необработанные данные, но похоже, что вы правы. Я собираюсь изменить это в свой ответ для тех, кто смотрит на этот вопрос в будущем. –

Смежные вопросы