NSData+XMPP.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #import "NSData+XMPP.h"
  2. #import <CommonCrypto/CommonDigest.h>
  3. #if ! __has_feature(objc_arc)
  4. #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
  5. #endif
  6. @implementation NSData (XMPP)
  7. static char encodingTable[64] = {
  8. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
  9. 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
  10. 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
  11. 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' };
  12. - (NSData *)xmpp_md5Digest
  13. {
  14. unsigned char result[CC_MD5_DIGEST_LENGTH];
  15. CC_MD5([self bytes], (CC_LONG)[self length], result);
  16. return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH];
  17. }
  18. - (NSData *)xmpp_sha1Digest
  19. {
  20. unsigned char result[CC_SHA1_DIGEST_LENGTH];
  21. CC_SHA1([self bytes], (CC_LONG)[self length], result);
  22. return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH];
  23. }
  24. - (NSString *)xmpp_hexStringValue
  25. {
  26. NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)];
  27. const unsigned char *dataBuffer = [self bytes];
  28. int i;
  29. for (i = 0; i < [self length]; ++i)
  30. {
  31. [stringBuffer appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
  32. }
  33. return [stringBuffer copy];
  34. }
  35. - (NSString *)xmpp_base64Encoded
  36. {
  37. const unsigned char *bytes = [self bytes];
  38. NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
  39. unsigned long ixtext = 0;
  40. unsigned long lentext = [self length];
  41. long ctremaining = 0;
  42. unsigned char inbuf[3], outbuf[4];
  43. unsigned short i = 0;
  44. unsigned short charsonline = 0, ctcopy = 0;
  45. unsigned long ix = 0;
  46. while( YES )
  47. {
  48. ctremaining = lentext - ixtext;
  49. if( ctremaining <= 0 ) break;
  50. for( i = 0; i < 3; i++ ) {
  51. ix = ixtext + i;
  52. if( ix < lentext ) inbuf[i] = bytes[ix];
  53. else inbuf [i] = 0;
  54. }
  55. outbuf [0] = (inbuf [0] & 0xFC) >> 2;
  56. outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
  57. outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
  58. outbuf [3] = inbuf [2] & 0x3F;
  59. ctcopy = 4;
  60. switch( ctremaining )
  61. {
  62. case 1:
  63. ctcopy = 2;
  64. break;
  65. case 2:
  66. ctcopy = 3;
  67. break;
  68. }
  69. for( i = 0; i < ctcopy; i++ )
  70. [result appendFormat:@"%c", encodingTable[outbuf[i]]];
  71. for( i = ctcopy; i < 4; i++ )
  72. [result appendString:@"="];
  73. ixtext += 3;
  74. charsonline += 4;
  75. }
  76. return [NSString stringWithString:result];
  77. }
  78. - (NSData *)xmpp_base64Decoded
  79. {
  80. const unsigned char *bytes = [self bytes];
  81. NSMutableData *result = [NSMutableData dataWithCapacity:[self length]];
  82. unsigned long ixtext = 0;
  83. unsigned long lentext = [self length];
  84. unsigned char ch = 0;
  85. unsigned char inbuf[4] = {0, 0, 0, 0};
  86. unsigned char outbuf[3] = {0, 0, 0};
  87. short i = 0, ixinbuf = 0;
  88. BOOL flignore = NO;
  89. BOOL flendtext = NO;
  90. while( YES )
  91. {
  92. if( ixtext >= lentext ) break;
  93. ch = bytes[ixtext++];
  94. flignore = NO;
  95. if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
  96. else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
  97. else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
  98. else if( ch == '+' ) ch = 62;
  99. else if( ch == '=' ) flendtext = YES;
  100. else if( ch == '/' ) ch = 63;
  101. else flignore = YES;
  102. if( ! flignore )
  103. {
  104. short ctcharsinbuf = 3;
  105. BOOL flbreak = NO;
  106. if( flendtext )
  107. {
  108. if( ! ixinbuf ) break;
  109. if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
  110. else ctcharsinbuf = 2;
  111. ixinbuf = 3;
  112. flbreak = YES;
  113. }
  114. inbuf [ixinbuf++] = ch;
  115. if( ixinbuf == 4 )
  116. {
  117. ixinbuf = 0;
  118. outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
  119. outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
  120. outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
  121. for( i = 0; i < ctcharsinbuf; i++ )
  122. [result appendBytes:&outbuf[i] length:1];
  123. }
  124. if( flbreak ) break;
  125. }
  126. }
  127. return [NSData dataWithData:result];
  128. }
  129. - (BOOL)xmpp_isJPEG
  130. {
  131. if (self.length > 4)
  132. {
  133. unsigned char buffer[4];
  134. [self getBytes:&buffer length:4];
  135. return buffer[0]==0xff &&
  136. buffer[1]==0xd8 &&
  137. buffer[2]==0xff &&
  138. buffer[3]==0xe0;
  139. }
  140. return NO;
  141. }
  142. - (BOOL)xmpp_isPNG
  143. {
  144. if (self.length > 4)
  145. {
  146. unsigned char buffer[4];
  147. [self getBytes:&buffer length:4];
  148. return buffer[0]==0x89 &&
  149. buffer[1]==0x50 &&
  150. buffer[2]==0x4e &&
  151. buffer[3]==0x47;
  152. }
  153. return NO;
  154. }
  155. - (NSString *)xmpp_imageType
  156. {
  157. NSString *result = nil;
  158. if([self xmpp_isPNG])
  159. {
  160. result = @"image/png";
  161. }
  162. else if([self xmpp_isJPEG])
  163. {
  164. result = @"image/jpeg";
  165. }
  166. return result;
  167. }
  168. @end
  169. #ifndef XMPP_EXCLUDE_DEPRECATED
  170. @implementation NSData (XMPPDeprecated)
  171. - (NSData *)md5Digest {
  172. return [self xmpp_md5Digest];
  173. }
  174. - (NSData *)sha1Digest {
  175. return [self xmpp_sha1Digest];
  176. }
  177. - (NSString *)hexStringValue {
  178. return [self xmpp_hexStringValue];
  179. }
  180. - (NSString *)base64Encoded {
  181. return [self xmpp_base64Encoded];
  182. }
  183. - (NSData *)base64Decoded {
  184. return [self xmpp_base64Decoded];
  185. }
  186. @end
  187. #endif