NSString+Hash.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //
  2. // NSString+Hash.m
  3. //
  4. #import "NSString+Hash.h"
  5. #import <CommonCrypto/CommonCrypto.h>
  6. @implementation NSString (Hash)
  7. #pragma mark - 散列函数
  8. - (NSString *)md5String {
  9. const char *str = self.UTF8String;
  10. uint8_t buffer[CC_MD5_DIGEST_LENGTH];
  11. CC_MD5(str, (CC_LONG)strlen(str), buffer);
  12. return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
  13. }
  14. - (NSString *)sha1String {
  15. const char *str = self.UTF8String;
  16. uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
  17. CC_SHA1(str, (CC_LONG)strlen(str), buffer);
  18. return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
  19. }
  20. - (NSString *)sha256String {
  21. const char *str = self.UTF8String;
  22. uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
  23. CC_SHA256(str, (CC_LONG)strlen(str), buffer);
  24. return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
  25. }
  26. - (NSString *)sha512String {
  27. const char *str = self.UTF8String;
  28. uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
  29. CC_SHA512(str, (CC_LONG)strlen(str), buffer);
  30. return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
  31. }
  32. #pragma mark - HMAC 散列函数
  33. - (NSString *)hmacMD5StringWithKey:(NSString *)key {
  34. const char *keyData = key.UTF8String;
  35. const char *strData = self.UTF8String;
  36. uint8_t buffer[CC_MD5_DIGEST_LENGTH];
  37. CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
  38. return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
  39. }
  40. - (NSString *)hmacSHA1StringWithKey:(NSString *)key {
  41. const char *keyData = key.UTF8String;
  42. const char *strData = self.UTF8String;
  43. uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
  44. CCHmac(kCCHmacAlgSHA1, keyData, strlen(keyData), strData, strlen(strData), buffer);
  45. return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
  46. }
  47. - (NSString *)hmacSHA256StringWithKey:(NSString *)key {
  48. const char *keyData = key.UTF8String;
  49. const char *strData = self.UTF8String;
  50. uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
  51. CCHmac(kCCHmacAlgSHA256, keyData, strlen(keyData), strData, strlen(strData), buffer);
  52. return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
  53. }
  54. - (NSString *)hmacSHA512StringWithKey:(NSString *)key {
  55. const char *keyData = key.UTF8String;
  56. const char *strData = self.UTF8String;
  57. uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
  58. CCHmac(kCCHmacAlgSHA512, keyData, strlen(keyData), strData, strlen(strData), buffer);
  59. return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
  60. }
  61. #pragma mark - 文件散列函数
  62. #define FileHashDefaultChunkSizeForReadingData 4096
  63. - (NSString *)fileMD5Hash {
  64. NSFileHandle *fp = [NSFileHandle fileHandleForReadingAtPath:self];
  65. if (fp == nil) {
  66. return nil;
  67. }
  68. CC_MD5_CTX hashCtx;
  69. CC_MD5_Init(&hashCtx);
  70. while (YES) {
  71. @autoreleasepool {
  72. NSData *data = [fp readDataOfLength:FileHashDefaultChunkSizeForReadingData];
  73. CC_MD5_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
  74. if (data.length == 0) {
  75. break;
  76. }
  77. }
  78. }
  79. [fp closeFile];
  80. uint8_t buffer[CC_MD5_DIGEST_LENGTH];
  81. CC_MD5_Final(buffer, &hashCtx);
  82. return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
  83. }
  84. - (NSString *)fileSHA1Hash {
  85. NSFileHandle *fp = [NSFileHandle fileHandleForReadingAtPath:self];
  86. if (fp == nil) {
  87. return nil;
  88. }
  89. CC_SHA1_CTX hashCtx;
  90. CC_SHA1_Init(&hashCtx);
  91. while (YES) {
  92. @autoreleasepool {
  93. NSData *data = [fp readDataOfLength:FileHashDefaultChunkSizeForReadingData];
  94. CC_SHA1_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
  95. if (data.length == 0) {
  96. break;
  97. }
  98. }
  99. }
  100. [fp closeFile];
  101. uint8_t buffer[CC_SHA1_DIGEST_LENGTH];
  102. CC_SHA1_Final(buffer, &hashCtx);
  103. return [self stringFromBytes:buffer length:CC_SHA1_DIGEST_LENGTH];
  104. }
  105. - (NSString *)fileSHA256Hash {
  106. NSFileHandle *fp = [NSFileHandle fileHandleForReadingAtPath:self];
  107. if (fp == nil) {
  108. return nil;
  109. }
  110. CC_SHA256_CTX hashCtx;
  111. CC_SHA256_Init(&hashCtx);
  112. while (YES) {
  113. @autoreleasepool {
  114. NSData *data = [fp readDataOfLength:FileHashDefaultChunkSizeForReadingData];
  115. CC_SHA256_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
  116. if (data.length == 0) {
  117. break;
  118. }
  119. }
  120. }
  121. [fp closeFile];
  122. uint8_t buffer[CC_SHA256_DIGEST_LENGTH];
  123. CC_SHA256_Final(buffer, &hashCtx);
  124. return [self stringFromBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
  125. }
  126. - (NSString *)fileSHA512Hash {
  127. NSFileHandle *fp = [NSFileHandle fileHandleForReadingAtPath:self];
  128. if (fp == nil) {
  129. return nil;
  130. }
  131. CC_SHA512_CTX hashCtx;
  132. CC_SHA512_Init(&hashCtx);
  133. while (YES) {
  134. @autoreleasepool {
  135. NSData *data = [fp readDataOfLength:FileHashDefaultChunkSizeForReadingData];
  136. CC_SHA512_Update(&hashCtx, data.bytes, (CC_LONG)data.length);
  137. if (data.length == 0) {
  138. break;
  139. }
  140. }
  141. }
  142. [fp closeFile];
  143. uint8_t buffer[CC_SHA512_DIGEST_LENGTH];
  144. CC_SHA512_Final(buffer, &hashCtx);
  145. return [self stringFromBytes:buffer length:CC_SHA512_DIGEST_LENGTH];
  146. }
  147. #pragma mark -
  148. /**
  149. * 返回二进制 Bytes 流的字符串表示形式
  150. *
  151. * @param bytes 二进制 Bytes 数组
  152. * @param length 数组长度
  153. *
  154. * @return 字符串表示形式
  155. */
  156. - (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
  157. NSMutableString *strM = [NSMutableString string];
  158. for (int i = 0; i < length; i++) {
  159. [strM appendFormat:@"%02x", bytes[i]];
  160. }
  161. return [strM copy];
  162. }
  163. @end