1 /*** JoDes.h ***/
2
3 #import
4 #import
5 #import
6
7 @interfaceJoDes : NSObject8
9 + (NSString *) encode:(NSString *)str key:(NSString *)key;10 + (NSString *) decode:(NSString *)str key:(NSString *)key;11
12 @end
13
14
15 /*** JoDes.m ***/
16 //
17 //XLEncrytHelper.m18 //NewHoldGold19 //
20 //Created by 梁鑫磊 on 13-12-27.21 //Copyright (c) 2013年 zsgjs. All rights reserved.22 //23
24 #import "JoDes.h"
25
26 @interfaceJoDes()27
28 + (NSString *) encodeBase64WithString:(NSString *)strData;29 + (NSString *) encodeBase64WithData:(NSData *)objData;30 + (NSData *) decodeBase64WithString:(NSString *)strBase64;31
32 + (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey33 context:(CCOperation)encryptOrDecrypt;34
35 @end
36
37 @implementationJoDes38
39 + (NSString *) encode:(NSString *)str key:(NSString *)key40 {41 //doCipher 不能编汉字,所以要进行 url encode
42 NSMutableString* str1 =[JoDes urlEncode:str];43 NSMutableString* encode =[NSMutableString stringWithString:[JoDes doCipher:str1 key:key context:kCCEncrypt]];44 [JoDes formatSpecialCharacters:encode];45 returnencode;46 }47
48 + (NSString *) decode:(NSString *)str key:(NSString *)key49 {50 NSMutableString *str1 =[NSMutableString stringWithString:str];51 [JoDes reformatSpecialCharacters:str1];52 NSString *rt =[JoDes doCipher:str1 key:key context:kCCDecrypt];53 returnrt;54 }55
56 + (NSMutableString *)urlEncode:(NSString*)str57 {58 NSMutableString* encodeStr =[NSMutableString stringWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];59 [encodeStr replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];60 [encodeStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [encodeStr length])];61 returnencodeStr;62 }63
64 + (void)formatSpecialCharacters:(NSMutableString *)str65 {66 [str replaceOccurrencesOfString:@"+" withString:@"$$" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];67 [str replaceOccurrencesOfString:@"/" withString:@"@@" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];68 }69
70
71 + (void)reformatSpecialCharacters:(NSMutableString *)str72 {73 [str replaceOccurrencesOfString:@"$$" withString:@"+" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];74 [str replaceOccurrencesOfString:@"@@" withString:@"/" options:NSWidthInsensitiveSearch range:NSMakeRange(0, [str length])];75 }76
77 + (NSString *)encodeBase64WithString:(NSString *)strData {78 return[JoDes encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]];79 }80
81
82 + (NSString *)encodeBase64WithData:(NSData *)objData {83 NSString *encoding =nil;84 unsigned char *encodingBytes =NULL;85 @try{86 static char encodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";87 static NSUInteger paddingTable[] = {0,2,1};88
89 NSUInteger dataLength =[objData length];90 NSUInteger encodedBlocks = (dataLength * 8) / 24;91 NSUInteger padding = paddingTable[dataLength % 3];92 if( padding > 0 ) encodedBlocks++;93 NSUInteger encodedLength = encodedBlocks * 4;94
95 encodingBytes =malloc(encodedLength);96 if( encodingBytes !=NULL ) {97 NSUInteger rawBytesToProcess =dataLength;98 NSUInteger rawBaseIndex = 0;99 NSUInteger encodingBaseIndex = 0;100 unsigned char *rawBytes = (unsigned char *)[objData bytes];101 unsigned charrawByte1, rawByte2, rawByte3;102 while( rawBytesToProcess >= 3) {103 rawByte1 =rawBytes[rawBaseIndex];104 rawByte2 = rawBytes[rawBaseIndex+1];105 rawByte3 = rawBytes[rawBaseIndex+2];106 encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];107 encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];108 encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) | ((rawByte3 >> 6) & 0x03) ];109 encodingBytes[encodingBaseIndex+3] = encodingTable[(rawByte3 & 0x3F)];110
111 rawBaseIndex += 3;112 encodingBaseIndex += 4;113 rawBytesToProcess -= 3;114 }115 rawByte2 = 0;116 switch (dataLength-rawBaseIndex) {117 case 2:118 rawByte2 = rawBytes[rawBaseIndex+1];119 case 1:120 rawByte1 =rawBytes[rawBaseIndex];121 encodingBytes[encodingBaseIndex] = encodingTable[((rawByte1 >> 2) & 0x3F)];122 encodingBytes[encodingBaseIndex+1] = encodingTable[((rawByte1 << 4) & 0x30) | ((rawByte2 >> 4) & 0x0F) ];123 encodingBytes[encodingBaseIndex+2] = encodingTable[((rawByte2 << 2) & 0x3C) ];124 //we can skip rawByte3 since we have a partial block it would always be 0
125 break;126 }127 //compute location from where to begin inserting padding, it may overwrite some bytes from the partial block encoding128 //if their value was 0 (cases 1-2).
129 encodingBaseIndex = encodedLength -padding;130 while( padding-- > 0) {131 encodingBytes[encodingBaseIndex++] = '=';132 }133 encoding =[[NSString alloc] initWithBytes:encodingBytes length:encodedLength encoding:NSASCIIStringEncoding];134 }135 }136 @catch (NSException *exception) {137 encoding =nil;138 NSLog(@"WARNING: error occured while tring to encode base 32 data: %@", exception);139 }140 @finally{141 if( encodingBytes !=NULL ) {142 free( encodingBytes );143 }144 }145 returnencoding;146
147 }148
149 + (NSData *)decodeBase64WithString:(NSString *)strBase64 {150 NSData *data =nil;151 unsigned char *decodedBytes =NULL;152 @try{153 #define __ 255
154 static char decodingTable[256] ={155 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0x00 - 0x0F
156 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0x10 - 0x1F
157 __,__,__,__, __,__,__,__, __,__,__,62, __,__,__,63, //0x20 - 0x2F
158 52,53,54,55, 56,57,58,59, 60,61,__,__, __, 0,__,__, //0x30 - 0x3F
159 __, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, //0x40 - 0x4F
160 15,16,17,18, 19,20,21,22, 23,24,25,__, __,__,__,__, //0x50 - 0x5F
161 __,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, //0x60 - 0x6F
162 41,42,43,44, 45,46,47,48, 49,50,51,__, __,__,__,__, //0x70 - 0x7F
163 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0x80 - 0x8F
164 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0x90 - 0x9F
165 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xA0 - 0xAF
166 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xB0 - 0xBF
167 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xC0 - 0xCF
168 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xD0 - 0xDF
169 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xE0 - 0xEF
170 __,__,__,__, __,__,__,__, __,__,__,__, __,__,__,__, //0xF0 - 0xFF
171 };172 strBase64 = [strBase64 stringByReplacingOccurrencesOfString:@"=" withString:@""];173 NSData *encodedData =[strBase64 dataUsingEncoding:NSASCIIStringEncoding];174 unsigned char *encodedBytes = (unsigned char *)[encodedData bytes];175
176 NSUInteger encodedLength =[encodedData length];177 NSUInteger encodedBlocks = (encodedLength+3) >> 2;178 NSUInteger expectedDataLength = encodedBlocks * 3;179
180 unsigned char decodingBlock[4];181
182 decodedBytes =malloc(expectedDataLength);183 if( decodedBytes !=NULL ) {184
185 NSUInteger i = 0;186 NSUInteger j = 0;187 NSUInteger k = 0;188 unsigned charc;189 while( i > 4);197 decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);198 decodedBytes[k+2] = (decodingBlock[2] << 6) | (decodingBlock[3]);199 j = 0;200 k += 3;201 }202 }203 }204
205 //Process left over bytes, if any
206 if( j == 3) {207 decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);208 decodedBytes[k+1] = (decodingBlock[1] << 4) | (decodingBlock[2] >> 2);209 k += 2;210 } else if( j == 2) {211 decodedBytes[k] = (decodingBlock[0] << 2) | (decodingBlock[1] >> 4);212 k += 1;213 }214 data =[[NSData alloc] initWithBytes:decodedBytes length:k];215 }216 }217 @catch (NSException *exception) {218 data =nil;219 NSLog(@"WARNING: error occured while decoding base 32 string: %@", exception);220 }221 @finally{222 if( decodedBytes !=NULL ) {223 free( decodedBytes );224 }225 }226 returndata;227
228 }229
230
231 + (NSString *)doCipher:(NSString *)sTextIn key:(NSString *)sKey232 context:(CCOperation)encryptOrDecrypt {233 NSStringEncoding EnC =NSUTF8StringEncoding;234
235 NSMutableData *dTextIn;236 if (encryptOrDecrypt ==kCCDecrypt) {237 dTextIn =[[JoDes decodeBase64WithString:sTextIn] mutableCopy];238 }239 else{240 dTextIn =[[sTextIn dataUsingEncoding: EnC] mutableCopy];241 }242 NSMutableData * dKey =[[sKey dataUsingEncoding:EnC] mutableCopy];243 [dKey setLength:kCCBlockSizeDES];244 uint8_t *bufferPtr1 =NULL;245 size_t bufferPtrSize1 = 0;246 size_t movedBytes1 = 0;247 //uint8_t iv[kCCBlockSizeDES];248 //memset((void *) iv, 0x0, (size_t) sizeof(iv));249 //Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
250 bufferPtrSize1 = ([sTextIn length] + kCCKeySizeDES) & ~(kCCKeySizeDES -1);251 bufferPtr1 = malloc(bufferPtrSize1 * sizeof(uint8_t));252 memset((void *)bufferPtr1, 0x00, bufferPtrSize1);253
254 CCCrypt(encryptOrDecrypt, //CCOperation op
255 kCCAlgorithmDES, //CCAlgorithm alg
256 kCCOptionPKCS7Padding, //CCOptions options
257 [dKey bytes], //const void *key
258 [dKey length], //size_t keyLength//259 [dKey bytes], //const void *iv
260 [dTextIn bytes], //const void *dataIn
261 [dTextIn length], //size_t dataInLength
262 (void *)bufferPtr1, //void *dataOut
263 bufferPtrSize1, //size_t dataOutAvailable
264 &movedBytes1);265
266 //[dTextIn release];267 //[dKey release];
268
269 NSString *sResult;270 if (encryptOrDecrypt ==kCCDecrypt){271 sResult =[[NSString alloc] initWithData:[NSData dataWithBytes:bufferPtr1 length:movedBytes1] encoding:EnC];272 free(bufferPtr1);273 }274 else{275 NSData *dResult =[NSData dataWithBytes:bufferPtr1 length:movedBytes1];276 free(bufferPtr1);277 sResult =[JoDes encodeBase64WithData:dResult];278 }279 returnsResult;280 }281
282
283
284 @end