@@ -581,6 +581,15 @@ + (void) readFile:(NSString *)path
581581
582582# pragma mark - hash
583583
584+ typedef enum {
585+ HashAlgorithmMD5,
586+ HashAlgorithmSHA1,
587+ HashAlgorithmSHA224,
588+ HashAlgorithmSHA256,
589+ HashAlgorithmSHA384,
590+ HashAlgorithmSHA512,
591+ } HashAlgorithm;
592+
584593+ (void ) hash : (NSString *)path
585594 algorithm : (NSString *)algorithm
586595 resolver : (RCTPromiseResolveBlock)resolve
@@ -611,7 +620,11 @@ + (void) hash:(NSString *)path
611620 return ;
612621 }
613622
614- NSData *content = [[NSFileManager defaultManager ] contentsAtPath: path];
623+ NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath: path];
624+ if (fileHandle == nil ) {
625+ reject (@" EUNKNOWN" , [NSString stringWithFormat: @" Error opening '%@ ' for reading" , path], error);
626+ return ;
627+ }
615628
616629 NSArray *keys = [NSArray arrayWithObjects: @" md5" , @" sha1" , @" sha224" , @" sha256" , @" sha384" , @" sha512" , nil ];
617630
@@ -634,23 +647,97 @@ + (void) hash:(NSString *)path
634647
635648 unsigned char buffer[digestLength];
636649
650+ const NSUInteger chunkSize = 1024 * 1024 ; // 1 Megabyte
651+ NSData *dataChunk;
652+
653+ CC_MD5_CTX md5Context;
654+ CC_SHA1_CTX sha1Context;
655+ CC_SHA256_CTX sha256Context;
656+ CC_SHA512_CTX sha512Context;
657+ HashAlgorithm hashAlgorithm;
658+
637659 if ([algorithm isEqualToString: @" md5" ]) {
638- CC_MD5 (content.bytes , (CC_LONG)content.length , buffer);
660+ CC_MD5_Init (&md5Context);
661+ hashAlgorithm = HashAlgorithmMD5;
639662 } else if ([algorithm isEqualToString: @" sha1" ]) {
640- CC_SHA1 (content.bytes , (CC_LONG)content.length , buffer);
663+ CC_SHA1_Init (&sha1Context);
664+ hashAlgorithm = HashAlgorithmSHA1;
641665 } else if ([algorithm isEqualToString: @" sha224" ]) {
642- CC_SHA224 (content.bytes , (CC_LONG)content.length , buffer);
666+ CC_SHA224_Init (&sha256Context);
667+ hashAlgorithm = HashAlgorithmSHA224;
643668 } else if ([algorithm isEqualToString: @" sha256" ]) {
644- CC_SHA256 (content.bytes , (CC_LONG)content.length , buffer);
669+ CC_SHA256_Init (&sha256Context);
670+ hashAlgorithm = HashAlgorithmSHA256;
645671 } else if ([algorithm isEqualToString: @" sha384" ]) {
646- CC_SHA384 (content.bytes , (CC_LONG)content.length , buffer);
672+ CC_SHA384_Init (&sha512Context);
673+ hashAlgorithm = HashAlgorithmSHA384;
647674 } else if ([algorithm isEqualToString: @" sha512" ]) {
648- CC_SHA512 (content.bytes , (CC_LONG)content.length , buffer);
675+ CC_SHA512_Init (&sha512Context);
676+ hashAlgorithm = HashAlgorithmSHA512;
649677 } else {
650678 reject (@" EINVAL" , [NSString stringWithFormat: @" Invalid algorithm '%@ ', must be one of md5, sha1, sha224, sha256, sha384, sha512" , algorithm], nil );
651679 return ;
652680 }
653681
682+ while (true ) {
683+ @autoreleasepool {
684+ dataChunk = [fileHandle readDataUpToLength: chunkSize error: &error];
685+
686+ if (error) {
687+ return reject (@" EREAD" , [NSString stringWithFormat: @" Error reading file '%@ '" , path], error);
688+ break ;
689+ }
690+
691+ if (dataChunk == nil || dataChunk.length == 0 ) {
692+ break ;
693+ }
694+
695+ switch (hashAlgorithm) {
696+ case HashAlgorithmMD5:
697+ CC_MD5_Update (&md5Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
698+ break ;
699+ case HashAlgorithmSHA1:
700+ CC_SHA1_Update (&sha1Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
701+ break ;
702+ case HashAlgorithmSHA224:
703+ CC_SHA224_Update (&sha256Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
704+ break ;
705+ case HashAlgorithmSHA256:
706+ CC_SHA256_Update (&sha256Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
707+ break ;
708+ case HashAlgorithmSHA384:
709+ CC_SHA384_Update (&sha512Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
710+ break ;
711+ case HashAlgorithmSHA512:
712+ CC_SHA512_Update (&sha512Context, [dataChunk bytes ], CC_LONG ([dataChunk length ]));
713+ break ;
714+ }
715+
716+ dataChunk = nil ;
717+ }
718+ }
719+
720+ switch (hashAlgorithm) {
721+ case HashAlgorithmMD5:
722+ CC_MD5_Final (buffer, &md5Context);
723+ break ;
724+ case HashAlgorithmSHA1:
725+ CC_SHA1_Final (buffer, &sha1Context);
726+ break ;
727+ case HashAlgorithmSHA224:
728+ CC_SHA224_Final (buffer, &sha256Context);
729+ break ;
730+ case HashAlgorithmSHA256:
731+ CC_SHA256_Final (buffer, &sha256Context);
732+ break ;
733+ case HashAlgorithmSHA384:
734+ CC_SHA384_Final (buffer, &sha512Context);
735+ break ;
736+ case HashAlgorithmSHA512:
737+ CC_SHA512_Final (buffer, &sha512Context);
738+ break ;
739+ }
740+
654741 NSMutableString *output = [NSMutableString stringWithCapacity: digestLength * 2 ];
655742 for (int i = 0 ; i < digestLength; i++)
656743 [output appendFormat: @" %02x " ,buffer[i]];
0 commit comments