4

I need to calculate the CRC32 checksum in my iOS app, and found the post for CRC32 calculation here, https://stackoverflow.com/a/14533955/691626. The image is read from UIImagePickerController(sent the image file to email first, then used iPhone to read the email and saved it to camera roll, then used UIImagePickerController to open the file)

CGDataProviderRef provider = CGImageGetDataProvider(image.CGImage);
NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
uint32_t result = crc32(0, data.bytes, data.length);

However, the result does not match outputs(CRC32 or CRC32B) this website https://defuse.ca/checksums.htm generates.

With the same image file, I tried to verify it on Java

// fileName is the path to the file on local drive, for example, /Users/myName/Documents/myimage.jpg on Mac
Path path = Paths.get(fileName);
byte[] data = Files.readAllBytes(path);
CRC32 checksum = new CRC32();
checksum.update(data, 0, data.length);
result = checksum.getValue();

At least the result can match the CRC32B that the verification website generates. Do I use the library incorrectly in iOS? Would someone please advise?

UPDATE 1
Did another experiment

obtain a raw data from captureSession

NSData *rawData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];

convert the raw data to image

UIImage *originalImage = [[UIImage alloc] initWithData:rawData];

convert the image to JPEG representation (required by the server I am working on)

NSData *jpegData = UIImageJPEGRepresentation(image, 1.0);

Compute CRC32 checksum for the NSData jpegData

long long checksum1 = crc32(0, jpegData.bytes, jpegData.length);

save the NSData jpegData to Documents folder, reload it, compute its checksum

[jpegData writeToFile:filePath atomically:YES];
NSData *jpegDataFromDocuments = [NSData dataWithContentsOfFile:filePath];
long long checksum2 = crc32(0, jpegDataFromDocuments.bytes, jpegDataFromDocuments.length);

reload the data with file manager, compute its checksum

NSData *jpegDataByFileManager = [[NSFileManager defaultManager] contentsAtPath:filePath];
long long checksum3 = crc32(0, jpegDataByFileManager.bytes, jpegDataByFileManager.length);

I was expecting to see the different values for checksum1 and checksum2(or checksum3) because they are read in different way, but they are all the same. And they don't match the value computed by the Java code above.

UPDATE 2
I tried to add the file to the resource folder and read the file from the folder directly, now the crc 32 checksum matches on Java and iOS

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"myimage" ofType:@"jpg"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
uLong crc = crc32(0L, Z_NULL, 0);
long long checksum = crc32(crc, [fileData bytes], [fileData length]);
Community
  • 1
  • 1
Dino Tw
  • 3,167
  • 4
  • 34
  • 48
  • 1
    What are you trying to get the checksum of? How was image created? In the java example you're getting the image directly from a file, why not in the iOS case? CRC32 is endian-dependent, are you just getting a byte-swapped result? What crc32 library are you using? – David Berry Apr 08 '14 at 05:34
  • possible duplicate of [Get CRC checksum of an NSData in Objective-C](http://stackoverflow.com/questions/4115059/get-crc-checksum-of-an-nsdata-in-objective-c) – David Berry Apr 08 '14 at 05:37
  • @David, thank you for taking time to answer my question. Yes, I read that link already and that's how I use the crc32() in Ojbective-c. On the Java side, it's the java.util.zip.CRC32 class. Let me update my original post with more details. – Dino Tw Apr 08 '14 at 05:46

0 Answers0