@@ -611,7 +611,11 @@ + (void) hash:(NSString *)path
611611 return ;
612612 }
613613
614- NSData *content = [[NSFileManager defaultManager ] contentsAtPath: path];
614+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath: filePath error: &error];
615+ if (error) {
616+ reject (@" EUNKNOWN" , [NSString stringWithFormat: @" Error opening '%@ ' for reading" , path], error);
617+ return ;
618+ }
615619
616620 NSArray *keys = [NSArray arrayWithObjects: @" md5" , @" sha1" , @" sha224" , @" sha256" , @" sha384" , @" sha512" , nil ];
617621
@@ -634,23 +638,68 @@ + (void) hash:(NSString *)path
634638
635639 unsigned char buffer[digestLength];
636640
641+ const NSUInteger chunkSize = 1024 * 1024 ; // 1 Megabyte
642+ NSData *dataChunk;
643+
644+ CC_MD5_CTX md5Context;
645+ CC_SHA1_CTX sha1Context;
646+ CC_SHA224_CTX sha224Context;
647+ CC_SHA256_CTX sha256Context;
648+ CC_SHA384_CTX sha384Context;
649+ CC_SHA512_CTX sha512Context;
650+
637651 if ([algorithm isEqualToString: @" md5" ]) {
638- CC_MD5 (content. bytes , (CC_LONG)content. length , buffer );
652+ CC_MD5_Init (&md5Context );
639653 } else if ([algorithm isEqualToString: @" sha1" ]) {
640- CC_SHA1 (content. bytes , (CC_LONG)content. length , buffer );
654+ CC_MD5_Init (&sha1Context );
641655 } else if ([algorithm isEqualToString: @" sha224" ]) {
642- CC_SHA224 (content. bytes , (CC_LONG)content. length , buffer );
656+ CC_MD5_Init (&sha224Context );
643657 } else if ([algorithm isEqualToString: @" sha256" ]) {
644- CC_SHA256 (content. bytes , (CC_LONG)content. length , buffer );
658+ CC_MD5_Init (&sha256Context );
645659 } else if ([algorithm isEqualToString: @" sha384" ]) {
646- CC_SHA384 (content. bytes , (CC_LONG)content. length , buffer );
660+ CC_MD5_Init (&sha384Context );
647661 } else if ([algorithm isEqualToString: @" sha512" ]) {
648- CC_SHA512 (content. bytes , (CC_LONG)content. length , buffer );
662+ CC_MD5_Init (&sha512Context );
649663 } else {
650664 reject (@" EINVAL" , [NSString stringWithFormat: @" Invalid algorithm '%@ ', must be one of md5, sha1, sha224, sha256, sha384, sha512" , algorithm], nil );
651665 return ;
652666 }
653667
668+ while ((dataChunk = [fileHandle readDataOfLength: chunkSize error: &error])) {
669+ if (error) {
670+ return reject (@" EREAD" , [NSString stringWithFormat: @" Error reading file '%@ '" , path], error);
671+ break ;
672+ }
673+
674+ if ([algorithm isEqualToString: @" md5" ]) {
675+ CC_MD5_Update (&md5Context);
676+ } else if ([algorithm isEqualToString: @" sha1" ]) {
677+ CC_SHA1_Update (&sha1Context);
678+ } else if ([algorithm isEqualToString: @" sha224" ]) {
679+ CC_SHA224_Update (&sha224Context);
680+ } else if ([algorithm isEqualToString: @" sha256" ]) {
681+ CC_SHA256_Update (&sha256Context);
682+ } else if ([algorithm isEqualToString: @" sha384" ]) {
683+ CC_SHA384_Update (&sha384Context);
684+ } else if ([algorithm isEqualToString: @" sha512" ]) {
685+ CC_SHA512_Update (&sha512Context);
686+ }
687+ }
688+
689+ if ([algorithm isEqualToString: @" md5" ]) {
690+ CC_MD5_Final (buffer, &md5Context));
691+ } else if ([algorithm isEqualToString: @" sha1" ]) {
692+ CC_SHA1_Final (buffer, &sha1Context));
693+ } else if ([algorithm isEqualToString: @" sha224" ]) {
694+ CC_SHA224_Final (buffer, &sha224Context));
695+ } else if ([algorithm isEqualToString: @" sha256" ]) {
696+ CC_SHA256_Final (buffer, &sha256Context));
697+ } else if ([algorithm isEqualToString: @" sha384" ]) {
698+ CC_SHA384_Final (buffer, &sha384Context));
699+ } else if ([algorithm isEqualToString: @" sha512" ]) {
700+ CC_SHA512_Final (buffer, &sha512Context));
701+ }
702+
654703 NSMutableString *output = [NSMutableString stringWithCapacity: digestLength * 2 ];
655704 for (int i = 0 ; i < digestLength; i++)
656705 [output appendFormat: @" %02x " ,buffer[i]];
0 commit comments