天天看點

iOS DES+Base64 加密、解密

DES是一種分組資料加密技術(先将資料分成固定長度的小資料塊,之後進行加密),速度較快,适用于大量資料加密

3DES是一種基于DES的加密算法,使用3個不同密匙對同一個分組資料塊進行3次加密,如此以使得密文強度更高。

相較于DES和3DES算法而言,AES算法有着更高的速度和資源使用效率,安全級别也較之更高了,被稱為下一代加密标準。

用DES實作加密和解密的過程:(注釋是我自己了解添加。不對的地方望指出)

.h檔案中:

[cpp]  view plain  copy

  1. + (NSString *)encryptWithText:(NSString *)sText;//加密  
  2. + (NSString *)decryptWithText:(NSString *)sText;//解密  

.m檔案中  (導包: #import "GTMBase64.h"(下面說)   #import <CommonCrypto/CommonCryptor.h> )

[cpp]  view plain  copy

  1. + (NSString *)encryptWithText:(NSString *)sText  
  2. {  
  3.     //kCCEncrypt 加密  
  4.     return [self encrypt:sText encryptOrDecrypt:kCCEncrypt key:@"des"];  
  5. }  
  6. + (NSString *)decryptWithText:(NSString *)sText  
  7. {  
  8.     //kCCDecrypt 解密  
  9.     return [self encrypt:sText encryptOrDecrypt:kCCDecrypt key:@"des"];  
  10. }  
  11. + (NSString *)encrypt:(NSString *)sText encryptOrDecrypt:(CCOperation)encryptOperation key:(NSString *)key  
  12. {  
  13.     const void *dataIn;  
  14.     size_t dataInLength;  
  15.     if (encryptOperation == kCCDecrypt)//傳遞過來的是decrypt 解碼  
  16.     {  
  17.         //解碼 base64  
  18.         NSData *decryptData = [GTMBase64 decodeData:[sText dataUsingEncoding:NSUTF8StringEncoding]];//轉成utf-8并decode  
  19.         dataInLength = [decryptData length];  
  20.         dataIn = [decryptData bytes];  
  21.     }  
  22.     else  //encrypt  
  23.     {  
  24.         NSData* encryptData = [sText dataUsingEncoding:NSUTF8StringEncoding];  
  25.         dataInLength = [encryptData length];  
  26.         dataIn = (const void *)[encryptData bytes];  
  27.     }  
  28.     CCCryptorStatus ccStatus;  
  29.     uint8_t *dataOut = NULL; //可以了解位type/typedef 的縮寫(有效的維護了代碼,比如:一個人用int,一個人用long。最好用typedef來定義)  
  30.     size_t dataOutAvailable = 0; //size_t  是操作符sizeof傳回的結果類型  
  31.     size_t dataOutMoved = 0;  
  32.     dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);  
  33.     dataOut = malloc( dataOutAvailable * sizeof(uint8_t));  
  34.     memset((void *)dataOut, 0x0, dataOutAvailable);//将已開辟記憶體空間buffer的首 1 個位元組的值設為值 0  
  35.     NSString *initIv = @"12345678";  
  36.     const void *vkey = (const void *) [key UTF8String];  
  37.     const void *iv = (const void *) [initIv UTF8String];  
  38.     //CCCrypt函數 加密/解密  
  39.     ccStatus = CCCrypt(encryptOperation,//  加密/解密  
  40.                        kCCAlgorithmDES,//  加密根據哪個标準(des,3des,aes。。。。)  
  41.                        kCCOptionPKCS7Padding,//  選項分組密碼算法(des:對每塊分組加一次密  3DES:對每塊分組加三個不同的密)  
  42.                        vkey,  //密鑰    加密和解密的密鑰必須一緻  
  43.                        kCCKeySizeDES,//   DES 密鑰的大小(kCCKeySizeDES=8)  
  44.                        iv, //  可選的初始矢量  
  45.                        dataIn, // 資料的存儲單元  
  46.                        dataInLength,// 資料的大小  
  47.                        (void *)dataOut,// 用于傳回資料  
  48.                        dataOutAvailable,  
  49.                        &dataOutMoved);  
  50.     NSString *result = nil;  
  51.     if (encryptOperation == kCCDecrypt)//encryptOperation==1  解碼  
  52.     {  
  53.         //得到解密出來的data資料,改變為utf-8的字元串  
  54.         result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:NSUTF8StringEncoding] autorelease];  
  55.     }  
  56.     else //encryptOperation==0  (加密過程中,把加好密的資料轉成base64的)  
  57.     {  
  58.         //編碼 base64  
  59.         NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];  
  60.         result = [GTMBase64 stringByEncodingData:data];  
  61.     }  
  62.     return result;  
  63. }  

這裡用到了Base64.。。從網上找到了一些好的類,直接貼到這裡用

Base64.h

[cpp]  view plain  copy

  1. //  
  2. //  GTMBase64.h  
  3. //  
  4. //  Copyright 2006-2008 Google Inc.  
  5. //  
  6. //  Licensed under the Apache License, Version 2.0 (the "License"); you may not  
  7. //  use this file except in compliance with the License.  You may obtain a copy  
  8. //  of the License at  
  9. //  
  10. //  http://www.apache.org/licenses/LICENSE-2.0  
  11. //  
  12. //  Unless required by applicable law or agreed to in writing, software  
  13. //  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  
  14. //  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the  
  15. //  License for the specific language governing permissions and limitations under  
  16. //  the License.  
  17. //  
  18. #import <Foundation/Foundation.h>  
  19. #import "GTMDefines.h"  
  20. // GTMBase64  
  21. //  
  22. /// Helper for handling Base64 and WebSafeBase64 encodings  
  23. //  
  24. /// The webSafe methods use different character set and also the results aren't  
  25. /// always padded to a multiple of 4 characters.  This is done so the resulting  
  26. /// data can be used in urls and url query arguments without needing any  
  27. /// encoding.  You must use the webSafe* methods together, the data does not  
  28. /// interop with the RFC methods.  
  29. //  
  30. @interface GTMBase64 : NSObject  
  31. //  
  32. // Standard Base64 (RFC) handling  
  33. //  
  34. // encodeData:  
  35. //  
  36. /// Base64 encodes contents of the NSData object.  
  37. //  
  38. /// Returns:  
  39. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  40. //  
  41. +(NSData *)encodeData:(NSData *)data;  
  42. // decodeData:  
  43. //  
  44. /// Base64 decodes contents of the NSData object.  
  45. //  
  46. /// Returns:  
  47. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  48. //  
  49. +(NSData *)decodeData:(NSData *)data;  
  50. // encodeBytes:length:  
  51. //  
  52. /// Base64 encodes the data pointed at by |bytes|.  
  53. //  
  54. /// Returns:  
  55. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  56. //  
  57. +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length;  
  58. // decodeBytes:length:  
  59. //  
  60. /// Base64 decodes the data pointed at by |bytes|.  
  61. //  
  62. /// Returns:  
  63. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  64. //  
  65. +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length;  
  66. // stringByEncodingData:  
  67. //  
  68. /// Base64 encodes contents of the NSData object.  
  69. //  
  70. /// Returns:  
  71. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  72. //  
  73. +(NSString *)stringByEncodingData:(NSData *)data;  
  74. // stringByEncodingBytes:length:  
  75. //  
  76. /// Base64 encodes the data pointed at by |bytes|.  
  77. //  
  78. /// Returns:  
  79. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  80. //  
  81. +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length;  
  82. // decodeString:  
  83. //  
  84. /// Base64 decodes contents of the NSString.  
  85. //  
  86. /// Returns:  
  87. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  88. //  
  89. +(NSData *)decodeString:(NSString *)string;  
  90. //  
  91. // Modified Base64 encoding so the results can go onto urls.  
  92. //  
  93. // The changes are in the characters generated and also allows the result to  
  94. // not be padded to a multiple of 4.  
  95. // Must use the matching call to encode/decode, won't interop with the  
  96. // RFC versions.  
  97. //  
  98. // webSafeEncodeData:padded:  
  99. //  
  100. /// WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES  
  101. /// then padding characters are added so the result length is a multiple of 4.  
  102. //  
  103. /// Returns:  
  104. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  105. //  
  106. +(NSData *)webSafeEncodeData:(NSData *)data  
  107.                       padded:(BOOL)padded;  
  108. // webSafeDecodeData:  
  109. //  
  110. /// WebSafe Base64 decodes contents of the NSData object.  
  111. //  
  112. /// Returns:  
  113. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  114. //  
  115. +(NSData *)webSafeDecodeData:(NSData *)data;  
  116. // webSafeEncodeBytes:length:padded:  
  117. //  
  118. /// WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES  
  119. /// then padding characters are added so the result length is a multiple of 4.  
  120. //  
  121. /// Returns:  
  122. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  123. //  
  124. +(NSData *)webSafeEncodeBytes:(const void *)bytes  
  125.                        length:(NSUInteger)length  
  126.                        padded:(BOOL)padded;  
  127. // webSafeDecodeBytes:length:  
  128. //  
  129. /// WebSafe Base64 decodes the data pointed at by |bytes|.  
  130. //  
  131. /// Returns:  
  132. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  133. //  
  134. +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length;  
  135. // stringByWebSafeEncodingData:padded:  
  136. //  
  137. /// WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES  
  138. /// then padding characters are added so the result length is a multiple of 4.  
  139. //  
  140. /// Returns:  
  141. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  142. //  
  143. +(NSString *)stringByWebSafeEncodingData:(NSData *)data  
  144.                                   padded:(BOOL)padded;  
  145. // stringByWebSafeEncodingBytes:length:padded:  
  146. //  
  147. /// WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES  
  148. /// then padding characters are added so the result length is a multiple of 4.  
  149. //  
  150. /// Returns:  
  151. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  152. //  
  153. +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes  
  154.                                    length:(NSUInteger)length  
  155.                                    padded:(BOOL)padded;  
  156. // webSafeDecodeString:  
  157. //  
  158. /// WebSafe Base64 decodes contents of the NSString.  
  159. //  
  160. /// Returns:  
  161. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  162. //  
  163. +(NSData *)webSafeDecodeString:(NSString *)string;  
  164. @end  

Base64.m

[cpp]  view plain  copy

  1. //  
  2. //  GTMBase64.m  
  3. //  
  4. //  Copyright 2006-2008 Google Inc.  
  5. //  
  6. //  Licensed under the Apache License, Version 2.0 (the "License"); you may not  
  7. //  use this file except in compliance with the License.  You may obtain a copy  
  8. //  of the License at  
  9. //  
  10. //  http://www.apache.org/licenses/LICENSE-2.0  
  11. //  
  12. //  Unless required by applicable law or agreed to in writing, software  
  13. //  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  
  14. //  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the  
  15. //  License for the specific language governing permissions and limitations under  
  16. //  the License.  
  17. //  
  18. #import "GTMBase64.h"  
  19. #import "GTMDefines.h"  
  20. static const char *kBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  21. static const char *kWebSafeBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";  
  22. static const char kBase64PaddingChar = '=';  
  23. static const char kBase64InvalidChar = 99;  
  24. static const char kBase64DecodeChars[] = {  
  25.     // This array was generated by the following code:  
  26.     // #include <sys/time.h>  
  27.     // #include <stdlib.h>  
  28.     // #include <string.h>  
  29.     // main()  
  30.     // {  
  31.     //   static const char Base64[] =  
  32.     //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  33.     //   char *pos;  
  34.     //   int idx, i, j;  
  35.     //   printf("    ");  
  36.     //   for (i = 0; i < 255; i += 8) {  
  37.     //     for (j = i; j < i + 8; j++) {  
  38.     //       pos = strchr(Base64, j);  
  39.     //       if ((pos == NULL) || (j == 0))  
  40.     //         idx = 99;  
  41.     //       else  
  42.     //         idx = pos - Base64;  
  43.     //       if (idx == 99)  
  44.     //         printf(" %2d,     ", idx);  
  45.     //       else  
  46.     //         printf(" %2d,", idx, j);  
  47.     //     }  
  48.     //     printf("\n    ");  
  49.     //   }  
  50.     // }  
  51.     99,      99,      99,      99,      99,      99,      99,      99,  
  52.     99,      99,      99,      99,      99,      99,      99,      99,  
  53.     99,      99,      99,      99,      99,      99,      99,      99,  
  54.     99,      99,      99,      99,      99,      99,      99,      99,  
  55.     99,      99,      99,      99,      99,      99,      99,      99,  
  56.     99,      99,      99,      62, 99,      99,      99,      63,  
  57.     52, 53, 54, 55, 56, 57, 58, 59,  
  58.     60, 61, 99,      99,      99,      99,      99,      99,  
  59.     99,       0,  1,  2,  3,  4,  5,  6,  
  60.     7,  8,  9, 10, 11, 12, 13, 14,  
  61.     15, 16, 17, 18, 19, 20, 21, 22,  
  62.     23, 24, 25, 99,      99,      99,      99,      99,  
  63.     99,      26, 27, 28, 29, 30, 31, 32,  
  64.     33, 34, 35, 36, 37, 38, 39, 40,  
  65.     41, 42, 43, 44, 45, 46, 47, 48,  
  66.     49, 50, 51, 99,      99,      99,      99,      99,  
  67.     99,      99,      99,      99,      99,      99,      99,      99,  
  68.     99,      99,      99,      99,      99,      99,      99,      99,  
  69.     99,      99,      99,      99,      99,      99,      99,      99,  
  70.     99,      99,      99,      99,      99,      99,      99,      99,  
  71.     99,      99,      99,      99,      99,      99,      99,      99,  
  72.     99,      99,      99,      99,      99,      99,      99,      99,  
  73.     99,      99,      99,      99,      99,      99,      99,      99,  
  74.     99,      99,      99,      99,      99,      99,      99,      99,  
  75.     99,      99,      99,      99,      99,      99,      99,      99,  
  76.     99,      99,      99,      99,      99,      99,      99,      99,  
  77.     99,      99,      99,      99,      99,      99,      99,      99,  
  78.     99,      99,      99,      99,      99,      99,      99,      99,  
  79.     99,      99,      99,      99,      99,      99,      99,      99,  
  80.     99,      99,      99,      99,      99,      99,      99,      99,  
  81.     99,      99,      99,      99,      99,      99,      99,      99,  
  82.     99,      99,      99,      99,      99,      99,      99,      99  
  83. };  
  84. static const char kWebSafeBase64DecodeChars[] = {  
  85.     // This array was generated by the following code:  
  86.     // #include <sys/time.h>  
  87.     // #include <stdlib.h>  
  88.     // #include <string.h>  
  89.     // main()  
  90.     // {  
  91.     //   static const char Base64[] =  
  92.     //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";  
  93.     //   char *pos;  
  94.     //   int idx, i, j;  
  95.     //   printf("    ");  
  96.     //   for (i = 0; i < 255; i += 8) {  
  97.     //     for (j = i; j < i + 8; j++) {  
  98.     //       pos = strchr(Base64, j);  
  99.     //       if ((pos == NULL) || (j == 0))  
  100.     //         idx = 99;  
  101.     //       else  
  102.     //         idx = pos - Base64;  
  103.     //       if (idx == 99)  
  104.     //         printf(" %2d,     ", idx);  
  105.     //       else  
  106.     //         printf(" %2d,", idx, j);  
  107.     //     }  
  108.     //     printf("\n    ");  
  109.     //   }  
  110.     // }  
  111.     99,      99,      99,      99,      99,      99,      99,      99,  
  112.     99,      99,      99,      99,      99,      99,      99,      99,  
  113.     99,      99,      99,      99,      99,      99,      99,      99,  
  114.     99,      99,      99,      99,      99,      99,      99,      99,  
  115.     99,      99,      99,      99,      99,      99,      99,      99,  
  116.     99,      99,      99,      99,      99,      62, 99,      99,  
  117.     52, 53, 54, 55, 56, 57, 58, 59,  
  118.     60, 61, 99,      99,      99,      99,      99,      99,  
  119.     99,       0,  1,  2,  3,  4,  5,  6,  
  120.     7,  8,  9, 10, 11, 12, 13, 14,  
  121.     15, 16, 17, 18, 19, 20, 21, 22,  
  122.     23, 24, 25, 99,      99,      99,      99,      63,  
  123.     99,      26, 27, 28, 29, 30, 31, 32,  
  124.     33, 34, 35, 36, 37, 38, 39, 40,  
  125.     41, 42, 43, 44, 45, 46, 47, 48,  
  126.     49, 50, 51, 99,      99,      99,      99,      99,  
  127.     99,      99,      99,      99,      99,      99,      99,      99,  
  128.     99,      99,      99,      99,      99,      99,      99,      99,  
  129.     99,      99,      99,      99,      99,      99,      99,      99,  
  130.     99,      99,      99,      99,      99,      99,      99,      99,  
  131.     99,      99,      99,      99,      99,      99,      99,      99,  
  132.     99,      99,      99,      99,      99,      99,      99,      99,  
  133.     99,      99,      99,      99,      99,      99,      99,      99,  
  134.     99,      99,      99,      99,      99,      99,      99,      99,  
  135.     99,      99,      99,      99,      99,      99,      99,      99,  
  136.     99,      99,      99,      99,      99,      99,      99,      99,  
  137.     99,      99,      99,      99,      99,      99,      99,      99,  
  138.     99,      99,      99,      99,      99,      99,      99,      99,  
  139.     99,      99,      99,      99,      99,      99,      99,      99,  
  140.     99,      99,      99,      99,      99,      99,      99,      99,  
  141.     99,      99,      99,      99,      99,      99,      99,      99,  
  142.     99,      99,      99,      99,      99,      99,      99,      99  
  143. };  
  144. // Tests a charact to see if it's a whitespace character.  
  145. //  
  146. // Returns:  
  147. //   YES if the character is a whitespace character.  
  148. //   NO if the character is not a whitespace character.  
  149. //  
  150. FOUNDATION_STATIC_INLINE BOOL IsSpace(unsigned char c) {  
  151.     // we use our own mapping here because we don't want anything w/ locale  
  152.     // support.  
  153.     static BOOL kSpaces[256] = {  
  154.         0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  // 0-9  
  155.         1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 10-19  
  156.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 20-29  
  157.         0, 0, 1, 0, 0, 0, 0, 0, 0, 0,  // 30-39  
  158.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 40-49  
  159.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 50-59  
  160.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 60-69  
  161.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 70-79  
  162.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 80-89  
  163.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 90-99  
  164.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 100-109  
  165.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 110-119  
  166.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 120-129  
  167.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 130-139  
  168.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 140-149  
  169.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 150-159  
  170.         1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 160-169  
  171.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 170-179  
  172.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 180-189  
  173.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 190-199  
  174.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 200-209  
  175.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 210-219  
  176.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 220-229  
  177.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 230-239  
  178.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 240-249  
  179.         0, 0, 0, 0, 0, 1,              // 250-255  
  180.     };  
  181.     return kSpaces[c];  
  182. }  
  183. // Calculate how long the data will be once it's base64 encoded.  
  184. //  
  185. // Returns:  
  186. //   The guessed encoded length for a source length  
  187. //  
  188. FOUNDATION_STATIC_INLINE NSUInteger CalcEncodedLength(NSUInteger srcLen,  
  189.                                                       BOOL padded) {  
  190.     NSUInteger intermediate_result = 8 * srcLen + 5;  
  191.     NSUInteger len = intermediate_result / 6;  
  192.     if (padded) {  
  193.         len = ((len + 3) / 4) * 4;  
  194.     }  
  195.     return len;  
  196. }  
  197. // Tries to calculate how long the data will be once it's base64 decoded.  
  198. // Unlinke the above, this is always an upperbound, since the source data  
  199. // could have spaces and might end with the padding characters on them.  
  200. //  
  201. // Returns:  
  202. //   The guessed decoded length for a source length  
  203. //  
  204. FOUNDATION_STATIC_INLINE NSUInteger GuessDecodedLength(NSUInteger srcLen) {  
  205.     return (srcLen + 3) / 4 * 3;  
  206. }  
  207. @interface GTMBase64 (PrivateMethods)  
  208. +(NSData *)baseEncode:(const void *)bytes  
  209.                length:(NSUInteger)length  
  210.               charset:(const char *)charset  
  211.                padded:(BOOL)padded;  
  212. +(NSData *)baseDecode:(const void *)bytes  
  213.                length:(NSUInteger)length  
  214.               charset:(const char*)charset  
  215.        requirePadding:(BOOL)requirePadding;  
  216. +(NSUInteger)baseEncode:(const char *)srcBytes  
  217.                  srcLen:(NSUInteger)srcLen  
  218.               destBytes:(char *)destBytes  
  219.                 destLen:(NSUInteger)destLen  
  220.                 charset:(const char *)charset  
  221.                  padded:(BOOL)padded;  
  222. +(NSUInteger)baseDecode:(const char *)srcBytes  
  223.                  srcLen:(NSUInteger)srcLen  
  224.               destBytes:(char *)destBytes  
  225.                 destLen:(NSUInteger)destLen  
  226.                 charset:(const char *)charset  
  227.          requirePadding:(BOOL)requirePadding;  
  228. @end  
  229. @implementation GTMBase64  
  230. //  
  231. // Standard Base64 (RFC) handling  
  232. //  
  233. +(NSData *)encodeData:(NSData *)data {  
  234.     return [self baseEncode:[data bytes]  
  235.                      length:[data length]  
  236.                     charset:kBase64EncodeChars  
  237.                      padded:YES];  
  238. }  
  239. +(NSData *)decodeData:(NSData *)data {  
  240.     return [self baseDecode:[data bytes]  
  241.                      length:[data length]  
  242.                     charset:kBase64DecodeChars  
  243.              requirePadding:YES];  
  244. }  
  245. +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length {  
  246.     return [self baseEncode:bytes  
  247.                      length:length  
  248.                     charset:kBase64EncodeChars  
  249.                      padded:YES];  
  250. }  
  251. +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length {  
  252.     return [self baseDecode:bytes  
  253.                      length:length  
  254.                     charset:kBase64DecodeChars  
  255.              requirePadding:YES];  
  256. }  
  257. +(NSString *)stringByEncodingData:(NSData *)data {  
  258.     NSString *result = nil;  
  259.     NSData *converted = [self baseEncode:[data bytes]  
  260.                                   length:[data length]  
  261.                                  charset:kBase64EncodeChars  
  262.                                   padded:YES];  
  263.     if (converted) {  
  264.         result = [[[NSString alloc] initWithData:converted  
  265.                                         encoding:NSASCIIStringEncoding] autorelease];  
  266.     }  
  267.     return result;  
  268. }  
  269. +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length {  
  270.     NSString *result = nil;  
  271.     NSData *converted = [self baseEncode:bytes  
  272.                                   length:length  
  273.                                  charset:kBase64EncodeChars  
  274.                                   padded:YES];  
  275.     if (converted) {  
  276.         result = [[[NSString alloc] initWithData:converted  
  277.                                         encoding:NSASCIIStringEncoding] autorelease];  
  278.     }  
  279.     return result;  
  280. }  
  281. +(NSData *)decodeString:(NSString *)string {  
  282.     NSData *result = nil;  
  283.     NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];  
  284.     if (data) {  
  285.         result = [self baseDecode:[data bytes]  
  286.                            length:[data length]  
  287.                           charset:kBase64DecodeChars  
  288.                    requirePadding:YES];  
  289.     }  
  290.     return result;  
  291. }  
  292. //  
  293. // Modified Base64 encoding so the results can go onto urls.  
  294. //  
  295. // The changes are in the characters generated and also the result isn't  
  296. // padded to a multiple of 4.  
  297. // Must use the matching call to encode/decode, won't interop with the  
  298. // RFC versions.  
  299. //  
  300. +(NSData *)webSafeEncodeData:(NSData *)data  
  301.                       padded:(BOOL)padded {  
  302.     return [self baseEncode:[data bytes]  
  303.                      length:[data length]  
  304.                     charset:kWebSafeBase64EncodeChars  
  305.                      padded:padded];  
  306. }  
  307. +(NSData *)webSafeDecodeData:(NSData *)data {  
  308.     return [self baseDecode:[data bytes]  
  309.                      length:[data length]  
  310.                     charset:kWebSafeBase64DecodeChars  
  311.              requirePadding:NO];  
  312. }  
  313. +(NSData *)webSafeEncodeBytes:(const void *)bytes  
  314.                        length:(NSUInteger)length  
  315.                        padded:(BOOL)padded {  
  316.     return [self baseEncode:bytes  
  317.                      length:length  
  318.                     charset:kWebSafeBase64EncodeChars  
  319.                      padded:padded];  
  320. }  
  321. +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length {  
  322.     return [self baseDecode:bytes  
  323.                      length:length  
  324.                     charset:kWebSafeBase64DecodeChars  
  325.              requirePadding:NO];  
  326. }  
  327. +(NSString *)stringByWebSafeEncodingData:(NSData *)data  
  328.                                   padded:(BOOL)padded {  
  329.     NSString *result = nil;  
  330.     NSData *converted = [self baseEncode:[data bytes]  
  331.                                   length:[data length]  
  332.                                  charset:kWebSafeBase64EncodeChars  
  333.                                   padded:padded];  
  334.     if (converted) {  
  335.         result = [[[NSString alloc] initWithData:converted  
  336.                                         encoding:NSASCIIStringEncoding] autorelease];  
  337.     }  
  338.     return result;  
  339. }  
  340. +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes  
  341.                                    length:(NSUInteger)length  
  342.                                    padded:(BOOL)padded {  
  343.     NSString *result = nil;  
  344.     NSData *converted = [self baseEncode:bytes  
  345.                                   length:length  
  346.                                  charset:kWebSafeBase64EncodeChars  
  347.                                   padded:padded];  
  348.     if (converted) {  
  349.         result = [[[NSString alloc] initWithData:converted  
  350.                                         encoding:NSASCIIStringEncoding] autorelease];  
  351.     }  
  352.     return result;  
  353. }  
  354. +(NSData *)webSafeDecodeString:(NSString *)string {  
  355.     NSData *result = nil;  
  356.     NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];  
  357.     if (data) {  
  358.         result = [self baseDecode:[data bytes]  
  359.                            length:[data length]  
  360.                           charset:kWebSafeBase64DecodeChars  
  361.                    requirePadding:NO];  
  362.     }  
  363.     return result;  
  364. }  
  365. @end  
  366. @implementation GTMBase64 (PrivateMethods)  
  367. //  
  368. // baseEncode:length:charset:padded:  
  369. //  
  370. // Does the common lifting of creating the dest NSData.  it creates & sizes the  
  371. // data for the results.  |charset| is the characters to use for the encoding  
  372. // of the data.  |padding| controls if the encoded data should be padded to a  
  373. // multiple of 4.  
  374. //  
  375. // Returns:  
  376. //   an autorelease NSData with the encoded data, nil if any error.  
  377. //  
  378. +(NSData *)baseEncode:(const void *)bytes  
  379.                length:(NSUInteger)length  
  380.               charset:(const char *)charset  
  381.                padded:(BOOL)padded {  
  382.     // how big could it be?  
  383.     NSUInteger maxLength = CalcEncodedLength(length, padded);  
  384.     // make space  
  385.     NSMutableData *result = [NSMutableData data];  
  386.     [result setLength:maxLength];  
  387.     // do it  
  388.     NSUInteger finalLength = [self baseEncode:bytes  
  389.                                        srcLen:length  
  390.                                     destBytes:[result mutableBytes]  
  391.                                       destLen:[result length]  
  392.                                       charset:charset  
  393.                                        padded:padded];  
  394.     if (finalLength) {  
  395.         _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?");  
  396.     } else {  
  397.         // shouldn't happen, this means we ran out of space  
  398.         result = nil;  
  399.     }  
  400.     return result;  
  401. }  
  402. //  
  403. // baseDecode:length:charset:requirePadding:  
  404. //  
  405. // Does the common lifting of creating the dest NSData.  it creates & sizes the  
  406. // data for the results.  |charset| is the characters to use for the decoding  
  407. // of the data.  
  408. //  
  409. // Returns:  
  410. //   an autorelease NSData with the decoded data, nil if any error.  
  411. //  
  412. //  
  413. +(NSData *)baseDecode:(const void *)bytes  
  414.                length:(NSUInteger)length  
  415.               charset:(const char *)charset  
  416.        requirePadding:(BOOL)requirePadding {  
  417.     // could try to calculate what it will end up as  
  418.     NSUInteger maxLength = GuessDecodedLength(length);  
  419.     // make space  
  420.     NSMutableData *result = [NSMutableData data];  
  421.     [result setLength:maxLength];  
  422.     // do it  
  423.     NSUInteger finalLength = [self baseDecode:bytes  
  424.                                        srcLen:length  
  425.                                     destBytes:[result mutableBytes]  
  426.                                       destLen:[result length]  
  427.                                       charset:charset  
  428.                                requirePadding:requirePadding];  
  429.     if (finalLength) {  
  430.         if (finalLength != maxLength) {  
  431.             // resize down to how big it was  
  432.             [result setLength:finalLength];  
  433.         }  
  434.     } else {  
  435.         // either an error in the args, or we ran out of space  
  436.         result = nil;  
  437.     }  
  438.     return result;  
  439. }  
  440. //  
  441. // baseEncode:srcLen:destBytes:destLen:charset:padded:  
  442. //  
  443. // Encodes the buffer into the larger.  returns the length of the encoded  
  444. // data, or zero for an error.  
  445. // |charset| is the characters to use for the encoding  
  446. // |padded| tells if the result should be padded to a multiple of 4.  
  447. //  
  448. // Returns:  
  449. //   the length of the encoded data.  zero if any error.  
  450. //  
  451. +(NSUInteger)baseEncode:(const char *)srcBytes  
  452.                  srcLen:(NSUInteger)srcLen  
  453.               destBytes:(char *)destBytes  
  454.                 destLen:(NSUInteger)destLen  
  455.                 charset:(const char *)charset  
  456.                  padded:(BOOL)padded {  
  457.     if (!srcLen || !destLen || !srcBytes || !destBytes) {  
  458.         return 0;  
  459.     }  
  460.     char *curDest = destBytes;  
  461.     const unsigned char *curSrc = (const unsigned char *)(srcBytes);  
  462.     // Three bytes of data encodes to four characters of cyphertext.  
  463.     // So we can pump through three-byte chunks atomically.  
  464.     while (srcLen > 2) {  
  465.         // space?  
  466.         _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");  
  467.         curDest[0] = charset[curSrc[0] >> 2];  
  468.         curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];  
  469.         curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)];  
  470.         curDest[3] = charset[curSrc[2] & 0x3f];  
  471.         curDest += 4;  
  472.         curSrc += 3;  
  473.         srcLen -= 3;  
  474.         destLen -= 4;  
  475.     }  
  476.     // now deal with the tail (<=2 bytes)  
  477.     switch (srcLen) {  
  478.         case 0:  
  479.             // Nothing left; nothing more to do.  
  480.             break;  
  481.         case 1:  
  482.             // One byte left: this encodes to two characters, and (optionally)  
  483.             // two pad characters to round out the four-character cypherblock.  
  484.             _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");  
  485.             curDest[0] = charset[curSrc[0] >> 2];  
  486.             curDest[1] = charset[(curSrc[0] & 0x03) << 4];  
  487.             curDest += 2;  
  488.             destLen -= 2;  
  489.             if (padded) {  
  490.                 _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");  
  491.                 curDest[0] = kBase64PaddingChar;  
  492.                 curDest[1] = kBase64PaddingChar;  
  493.                 curDest += 2;  
  494.                 destLen -= 2;  
  495.             }  
  496.             break;  
  497.         case 2:  
  498.             // Two bytes left: this encodes to three characters, and (optionally)  
  499.             // one pad character to round out the four-character cypherblock.  
  500.             _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong");  
  501.             curDest[0] = charset[curSrc[0] >> 2];  
  502.             curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];  
  503.             curDest[2] = charset[(curSrc[1] & 0x0f) << 2];  
  504.             curDest += 3;  
  505.             destLen -= 3;  
  506.             if (padded) {  
  507.                 _GTMDevAssert(destLen >= 1, @"our calc for encoded length was wrong");  
  508.                 curDest[0] = kBase64PaddingChar;  
  509.                 curDest += 1;  
  510.                 destLen -= 1;  
  511.             }  
  512.             break;  
  513.     }  
  514.     // return the length  
  515.     return (curDest - destBytes);  
  516. }  
  517. //  
  518. // baseDecode:srcLen:destBytes:destLen:charset:requirePadding:  
  519. //  
  520. // Decodes the buffer into the larger.  returns the length of the decoded  
  521. // data, or zero for an error.  
  522. // |charset| is the character decoding buffer to use  
  523. //  
  524. // Returns:  
  525. //   the length of the encoded data.  zero if any error.  
  526. //  
  527. +(NSUInteger)baseDecode:(const char *)srcBytes  
  528.                  srcLen:(NSUInteger)srcLen  
  529.               destBytes:(char *)destBytes  
  530.                 destLen:(NSUInteger)destLen  
  531.                 charset:(const char *)charset  
  532.          requirePadding:(BOOL)requirePadding {  
  533.     if (!srcLen || !destLen || !srcBytes || !destBytes) {  
  534.         return 0;  
  535.     }  
  536.     int decode;  
  537.     NSUInteger destIndex = 0;  
  538.     int state = 0;  
  539.     char ch = 0;  
  540.     while (srcLen-- && (ch = *srcBytes++) != 0)  {  
  541.         if (IsSpace(ch))  // Skip whitespace  
  542.             continue;  
  543.         if (ch == kBase64PaddingChar)  
  544.             break;  
  545.         decode = charset[(unsigned int)ch];  
  546.         if (decode == kBase64InvalidChar)  
  547.             return 0;  
  548.         // Four cyphertext characters decode to three bytes.  
  549.         // Therefore we can be in one of four states.  
  550.         switch (state) {  
  551.             case 0:  
  552.                 // We're at the beginning of a four-character cyphertext block.  
  553.                 // This sets the high six bits of the first byte of the  
  554.                 // plaintext block.  
  555.                 _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");  
  556.                 destBytes[destIndex] = decode << 2;  
  557.                 state = 1;  
  558.                 break;  
  559.             case 1:  
  560.                 // We're one character into a four-character cyphertext block.  
  561.                 // This sets the low two bits of the first plaintext byte,  
  562.                 // and the high four bits of the second plaintext byte.  
  563.                 _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");  
  564.                 destBytes[destIndex] |= decode >> 4;  
  565.                 destBytes[destIndex+1] = (decode & 0x0f) << 4;  
  566.                 destIndex++;  
  567.                 state = 2;  
  568.                 break;  
  569.             case 2:  
  570.                 // We're two characters into a four-character cyphertext block.  
  571.                 // This sets the low four bits of the second plaintext  
  572.                 // byte, and the high two bits of the third plaintext byte.  
  573.                 // However, if this is the end of data, and those two  
  574.                 // bits are zero, it could be that those two bits are  
  575.                 // leftovers from the encoding of data that had a length  
  576.                 // of two mod three.  
  577.                 _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");  
  578.                 destBytes[destIndex] |= decode >> 2;  
  579.                 destBytes[destIndex+1] = (decode & 0x03) << 6;  
  580.                 destIndex++;  
  581.                 state = 3;  
  582.                 break;  
  583.             case 3:  
  584.                 // We're at the last character of a four-character cyphertext block.  
  585.                 // This sets the low six bits of the third plaintext byte.  
  586.                 _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");  
  587.                 destBytes[destIndex] |= decode;  
  588.                 destIndex++;  
  589.                 state = 0;  
  590.                 break;  
  591.         }  
  592.     }  
  593.     // We are done decoding Base-64 chars.  Let's see if we ended  
  594.     //      on a byte boundary, and/or with erroneous trailing characters.  
  595.     if (ch == kBase64PaddingChar) {               // We got a pad char  
  596.         if ((state == 0) || (state == 1)) {  
  597.             return 0;  // Invalid '=' in first or second position  
  598.         }  
  599.         if (srcLen == 0) {  
  600.             if (state == 2) { // We run out of input but we still need another '='  
  601.                 return 0;  
  602.             }  
  603.             // Otherwise, we are in state 3 and only need this '='  
  604.         } else {  
  605.             if (state == 2) {  // need another '='  
  606.                 while ((ch = *srcBytes++) && (srcLen-- > 0)) {  
  607.                     if (!IsSpace(ch))  
  608.                         break;  
  609.                 }  
  610.                 if (ch != kBase64PaddingChar) {  
  611.                     return 0;  
  612.                 }  
  613.             }  
  614.             // state = 1 or 2, check if all remain padding is space  
  615.             while ((ch = *srcBytes++) && (srcLen-- > 0)) {  
  616.                 if (!IsSpace(ch)) {  
  617.                     return 0;  
  618.                 }  
  619.             }  
  620.         }  
  621.     } else {  
  622.         // We ended by seeing the end of the string.  
  623.         if (requirePadding) {  
  624.             // If we require padding, then anything but state 0 is an error.  
  625.             if (state != 0) {  
  626.                 return 0;  
  627.             }  
  628.         } else {  
  629.             // Make sure we have no partial bytes lying around.  Note that we do not  
  630.             // require trailing '=', so states 2 and 3 are okay too.  
  631.             if (state == 1) {  
  632.                 return 0;  
  633.             }  
  634.         }  
  635.     }  
  636.     // If then next piece of output was valid and got written to it means we got a  
  637.     // very carefully crafted input that appeared valid but contains some trailing  
  638.     // bits past the real length, so just toss the thing.  
  639.     if ((destIndex < destLen) &&  
  640.         (destBytes[destIndex] != 0)) {  
  641.         return 0;  
  642.     }  
  643.     return destIndex;  
  644. }  
  645. @end  

在Base64 代碼中用到了一個.h檔案

Defines.h

[cpp]  view plain  copy

  1. //  
  2. // GTMDefines.h  
  3. //  
  4. //  Copyright 2008 Google Inc.  
  5. //  
  6. //  Licensed under the Apache License, Version 2.0 (the "License"); you may not  
  7. //  use this file except in compliance with the License.  You may obtain a copy  
  8. //  of the License at  
  9. //  
  10. //  http://www.apache.org/licenses/LICENSE-2.0  
  11. //  
  12. //  Unless required by applicable law or agreed to in writing, software  
  13. //  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT  
  14. //  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the  
  15. //  License for the specific language governing permissions and limitations under  
  16. //  the License.  
  17. //  
  18. // ============================================================================  
  19. #include <AvailabilityMacros.h>  
  20. // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs  
  21. #ifndef MAC_OS_X_VERSION_10_5  
  22. #define MAC_OS_X_VERSION_10_5 1050  
  23. #endif  
  24. #ifndef MAC_OS_X_VERSION_10_6  
  25. #define MAC_OS_X_VERSION_10_6 1060  
  26. #endif  
  27. // ----------------------------------------------------------------------------  
  28. // CPP symbols that can be overridden in a prefix to control how the toolbox  
  29. // is compiled.  
  30. // ----------------------------------------------------------------------------  
  31. // GTMHTTPFetcher will support logging by default but only hook its input  
  32. // stream support for logging when requested.  You can control the inclusion of  
  33. // the code by providing your own definitions for these w/in a prefix header.  
  34. //  
  35. #ifndef GTM_HTTPFETCHER_ENABLE_LOGGING  
  36. #define GTM_HTTPFETCHER_ENABLE_LOGGING 1  
  37. #endif // GTM_HTTPFETCHER_ENABLE_LOGGING  
  38. #ifndef GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING  
  39. #define GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING 0  
  40. #endif // GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING  
  41. // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and  
  42. // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens  
  43. // when a validation fails. If you implement your own validators, you may want  
  44. // to control their internals using the same macros for consistency.  
  45. #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT  
  46. #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0  
  47. #endif  
  48. // Give ourselves a consistent way to do inlines.  Apple's macros even use  
  49. // a few different actual definitions, so we're based off of the foundation  
  50. // one.  
  51. #if !defined(GTM_INLINE)  
  52. #if defined (__GNUC__) && (__GNUC__ == 4)  
  53. #define GTM_INLINE static __inline__ __attribute__((always_inline))  
  54. #else  
  55. #define GTM_INLINE static __inline__  
  56. #endif  
  57. #endif  
  58. // Give ourselves a consistent way of doing externs that links up nicely  
  59. // when mixing objc and objc++  
  60. #if !defined (GTM_EXTERN)  
  61. #if defined __cplusplus  
  62. #define GTM_EXTERN extern "C"  
  63. #else  
  64. #define GTM_EXTERN extern  
  65. #endif  
  66. #endif  
  67. // Give ourselves a consistent way of exporting things if we have visibility  
  68. // set to hidden.  
  69. #if !defined (GTM_EXPORT)  
  70. #define GTM_EXPORT __attribute__((visibility("default")))  
  71. #endif  
  72. // _GTMDevLog & _GTMDevAssert  
  73. //  
  74. // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for  
  75. // developer level errors.  This implementation simply macros to NSLog/NSAssert.  
  76. // It is not intended to be a general logging/reporting system.  
  77. //  
  78. // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert  
  79. // for a little more background on the usage of these macros.  
  80. //  
  81. //    _GTMDevLog           log some error/problem in debug builds  
  82. //    _GTMDevAssert        assert if conditon isn't met w/in a method/function  
  83. //                           in all builds.  
  84. //  
  85. // To replace this system, just provide different macro definitions in your  
  86. // prefix header.  Remember, any implementation you provide *must* be thread  
  87. // safe since this could be called by anything in what ever situtation it has  
  88. // been placed in.  
  89. //  
  90. // We only define the simple macros if nothing else has defined this.  
  91. #ifndef _GTMDevLog  
  92. #ifdef DEBUG  
  93. #define _GTMDevLog(...) NSLog(__VA_ARGS__)  
  94. #else  
  95. #define _GTMDevLog(...) do { } while (0)  
  96. #endif  
  97. #endif // _GTMDevLog  
  98. // Declared here so that it can easily be used for logging tracking if  
  99. // necessary. See GTMUnitTestDevLog.h for details.  
  100. @class NSString;  
  101. GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);  
  102. #ifndef _GTMDevAssert  
  103. // we directly invoke the NSAssert handler so we can pass on the varargs  
  104. // (NSAssert doesn't have a macro we can use that takes varargs)  
  105. #if !defined(NS_BLOCK_ASSERTIONS)  
  106. #define _GTMDevAssert(condition, ...)                                       \  
  107. do {                                                                      \  
  108. if (!(condition)) {                                                     \  
  109. [[NSAssertionHandler currentHandler]                                  \  
  110. handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \  
  111. file:[NSString stringWithUTF8String:__FILE__]  \  
  112. lineNumber:__LINE__                                  \  
  113. description:__VA_ARGS__];                             \  
  114. }                                                                       \  
  115. } while(0)  
  116. #else // !defined(NS_BLOCK_ASSERTIONS)  
  117. #define _GTMDevAssert(condition, ...) do { } while (0)  
  118. #endif // !defined(NS_BLOCK_ASSERTIONS)  
  119. #endif // _GTMDevAssert  
  120. // _GTMCompileAssert  
  121. // _GTMCompileAssert is an assert that is meant to fire at compile time if you  
  122. // want to check things at compile instead of runtime. For example if you  
  123. // want to check that a wchar is 4 bytes instead of 2 you would use  
  124. // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)  
  125. // Note that the second "arg" is not in quotes, and must be a valid processor  
  126. // symbol in it's own right (no spaces, punctuation etc).  
  127. // Wrapping this in an #ifndef allows external groups to define their own  
  128. // compile time assert scheme.  
  129. #ifndef _GTMCompileAssert  
  130. // We got this technique from here:  
  131. // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html  
  132. #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg  
  133. #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)  
  134. #define _GTMCompileAssert(test, msg) \  
  135. typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]  
  136. #endif // _GTMCompileAssert  
  137. // Macro to allow fast enumeration when building for 10.5 or later, and  
  138. // reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration  
  139. // does keys, so pick the right thing, nothing is done on the FastEnumeration  
  140. // side to be sure you're getting what you wanted.  
  141. #ifndef GTM_FOREACH_OBJECT  
  142. #if defined(TARGET_OS_IPHONE) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)  
  143. #define GTM_FOREACH_OBJECT(element, collection) \  
  144. for (element in collection)  
  145. #define GTM_FOREACH_KEY(element, collection) \  
  146. for (element in collection)  
  147. #else  
  148. #define GTM_FOREACH_OBJECT(element, collection) \  
  149. for (NSEnumerator * _ ## element ## _enum = [collection objectEnumerator]; \  
  150. (element = [_ ## element ## _enum nextObject]) != nil; )  
  151. #define GTM_FOREACH_KEY(element, collection) \  
  152. for (NSEnumerator * _ ## element ## _enum = [collection keyEnumerator]; \  
  153. (element = [_ ## element ## _enum nextObject]) != nil; )  
  154. #endif  
  155. #endif  
  156. // ============================================================================  
  157. // ----------------------------------------------------------------------------  
  158. // CPP symbols defined based on the project settings so the GTM code has  
  159. // simple things to test against w/o scattering the knowledge of project  
  160. // setting through all the code.  
  161. // ----------------------------------------------------------------------------  
  162. // Provide a single constant CPP symbol that all of GTM uses for ifdefing  
  163. // iPhone code.  
  164. #include <TargetConditionals.h>  
  165. #if TARGET_OS_IPHONE // iPhone SDK  
  166. // For iPhone specific stuff  
  167. #define GTM_IPHONE_SDK 1  
  168. #if TARGET_IPHONE_SIMULATOR  
  169. #define GTM_IPHONE_SIMULATOR 1  
  170. #else  
  171. #define GTM_IPHONE_DEVICE 1  
  172. #endif  // TARGET_IPHONE_SIMULATOR  
  173. #else  
  174. // For MacOS specific stuff  
  175. #define GTM_MACOS_SDK 1  
  176. #endif  
  177. // Provide a symbol to include/exclude extra code for GC support.  (This mainly  
  178. // just controls the inclusion of finalize methods).  
  179. #ifndef GTM_SUPPORT_GC  
  180. #if GTM_IPHONE_SDK  
  181. // iPhone never needs GC  
  182. #define GTM_SUPPORT_GC 0  
  183. #else  
  184. // We can't find a symbol to tell if GC is supported/required, so best we  
  185. // do on Mac targets is include it if we're on 10.5 or later.  
  186. #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4  
  187. #define GTM_SUPPORT_GC 0  
  188. #else  
  189. #define GTM_SUPPORT_GC 1  
  190. #endif  
  191. #endif  
  192. #endif  
  193. // To simplify support for 64bit (and Leopard in general), we provide the type  
  194. // defines for non Leopard SDKs  
  195. #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4  
  196. // NSInteger/NSUInteger and Max/Mins  
  197. #ifndef NSINTEGER_DEFINED  
  198. #if __LP64__ || NS_BUILD_32_LIKE_64  
  199. typedef long NSInteger;  
  200. typedef unsigned long NSUInteger;  
  201. #else  
  202. typedef int NSInteger;  
  203. typedef unsigned int NSUInteger;  
  204. #endif  
  205. #define NSIntegerMax    LONG_MAX  
  206. #define NSIntegerMin    LONG_MIN  
  207. #define NSUIntegerMax   ULONG_MAX  
  208. #define NSINTEGER_DEFINED 1  
  209. #endif  // NSINTEGER_DEFINED  
  210. // CGFloat  
  211. #ifndef CGFLOAT_DEFINED  
  212. #if defined(__LP64__) && __LP64__  
  213. // This really is an untested path (64bit on Tiger?)  
  214. typedef double CGFloat;  
  215. #define CGFLOAT_MIN DBL_MIN  
  216. #define CGFLOAT_MAX DBL_MAX  
  217. #define CGFLOAT_IS_DOUBLE 1  
  218. #else   
  219. typedef float CGFloat;  
  220. #define CGFLOAT_MIN FLT_MIN  
  221. #define CGFLOAT_MAX FLT_MAX  
  222. #define CGFLOAT_IS_DOUBLE 0  
  223. #endif   
  224. #define CGFLOAT_DEFINED 1  
  225. #endif // CGFLOAT_DEFINED  
  226. #endif  // MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4  

調用方法測試:

[cpp]  view plain  copy

  1. NSString *encrypt = [ViewController encryptWithText:@"中華人民共和國萬歲!!"];  
  2.     NSLog(@"enctry = %@",encrypt);  
  3.     NSString *decrypt = [ViewController decryptWithText:encrypt];  
  4.     NSLog(@"decrypt = %@",decrypt);  

輸出結果:

enctry = IKnyVPAK8eprKHHunG7Ze9tTfU8sIoYho8SFeyFEniK/7wy3u7stKA==

decrypt =中華人民共和國萬歲!!