2012-06-08 186 views
2

我正在尝试计算ALAsset的CRC校验和。我的目标是保存所有的CRC,并在稍后比较它们以查看资产是否已更改,但每次为同一资产生成CRC时,我都会得到不同的结果。为ALAsset计算CRC校验和

要生成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
网址:资产库://asset/asset.JPG ID = BB282CBD-F5B1-4771-B48B -E021224C7384 & EXT = 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 *代表= [结果defaultRepresentation]; Byte * buffer =(Byte *)malloc(rep.size); NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil]; NSData * data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]; [assetData setCrc:[CRC32 CRC32Value:[NSData的dataWithBytes:([数据字节]) 长度:的sizeof(数据)]]];' – jtromo

+0

我很高兴你理解了它。我对Assets Library不熟悉,看起来很奇怪,这是获取原始数据的最佳方式,但看起来你是对的。我将把这个编辑成我的答案,供任何人在未来看到这个问题。 –