zoukankan      html  css  js  c++  java
  • 登录账号加密存在本地{des加密}

    APP现在要求账号和密码加密存在本地(用户选择保存密码,则账号和密码都存储在本地,否则只账号存在本地)

    考虑过情况后,试过用MD5,不可逆,存储在本地用NSUserDefault(里面存的是字典,字典里面包含账号和密码),当用户登陆的时候,选择账号,匹配密码,这时出了问题,因为加密后无法解密,而我拿出来的是加密过的数据,当我固定密码的长度时,又出现了问题(后台账号密码匹配也是MD5),后来不太记得了,一天一直没解决。回到家想换种思路,直接本地加密解密是否可以?

    第二天,找到des,用加密解密的方法很快实现了(网上找的des加密文件)

    //DES3Util.h

    #import <Foundation/Foundation.h>

    #import "GTMBase64.h"

    #import <CommonCrypto/CommonCryptor.h>

    @interface DES3Util : NSObject

    //加密方法

    +(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key;

    //解密方法

    +(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key;

    @end

    //DES3Util.m

    @implementation DES3Util

     const Byte iv[] = {1,2,3,4,5,6,7,8};

    //Des加密

     +(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key

     {

        

         NSString *ciphertext = nil;

         NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];

         NSUInteger dataLength = [textData length];

         unsigned char buffer[1024];

         memset(buffer, 0, sizeof(char));

         size_t numBytesEncrypted = 0;

         CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,

                                                    kCCOptionPKCS7Padding,

                                                  [key UTF8String], kCCKeySizeDES,

                                                                iv,

                                                    [textData bytes], dataLength,

                                                            buffer, 1024,

                                                        &numBytesEncrypted);

             if (cryptStatus == kCCSuccess) {

                     NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];

                     ciphertext = [GTMBase64 stringByEncodingData:data];

                 }

             return ciphertext;

         }

    //Des解密

     +(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key

     {

             NSString *plaintext = nil;

             NSData *cipherdata = [GTMBase64 decodeString:cipherText];

             unsigned char buffer[1024];

             memset(buffer, 0, sizeof(char));

             size_t numBytesDecrypted = 0;

             CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,

                                                               kCCOptionPKCS7Padding,

                                                               [key UTF8String], kCCKeySizeDES,

                                                               iv,

                                                               [cipherdata bytes], [cipherdata length],

                                                               buffer, 1024,

                                                               &numBytesDecrypted);

             if(cryptStatus == kCCSuccess)

             {

                    NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];

                     plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];

             }

         return plaintext;

         }

    @end

    //  GTMBase64.h

    #import <Foundation/Foundation.h>

    #import "GTMDefines.h"

    +(NSData *)encodeData:(NSData *)data;

    +(NSData *)decodeData:(NSData *)data;

    +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length;

    +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length;

    +(NSString *)stringByEncodingData:(NSData *)data;

    +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length;

    +(NSData *)decodeString:(NSString *)string;

    +(NSData *)webSafeEncodeData:(NSData *)data

                          padded:(BOOL)padded;

    +(NSData *)webSafeDecodeData:(NSData *)data;

    +(NSData *)webSafeEncodeBytes:(const void *)bytes

                           length:(NSUInteger)length

                           padded:(BOOL)padded;

    +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length;

    +(NSString *)stringByWebSafeEncodingData:(NSData *)data

                                      padded:(BOOL)padded;

    +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes

                                       length:(NSUInteger)length

                                       padded:(BOOL)padded;

    +(NSData *)webSafeDecodeString:(NSString *)string;

    @end

    //  GTMBase64.m

    static const char *kBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    static const char *kWebSafeBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

    static const char kBase64PaddingChar = '=';

    static const char kBase64InvalidChar = 99;

    static const char kBase64DecodeChars[] = {

        // This array was generated by the following code:

        // #include <sys/time.h>

        // #include <stdlib.h>

        // #include <string.h>

        // main()

        // {

        //   static const char Base64[] =

        //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        //   char *pos;

        //   int idx, i, j;

        //   printf("    ");

        //   for (i = 0; i < 255; i += 8) {

        //     for (j = i; j < i + 8; j++) {

        //       pos = strchr(Base64, j);

        //       if ((pos == NULL) || (j == 0))

        //         idx = 99;

        //       else

        //         idx = pos - Base64;

        //       if (idx == 99)

        //         printf(" %2d,     ", idx);

        //       else

        //         printf(" %2d/*%c*/,", idx, j);

        //     }

        //     printf("     ");

        //   }

        // }

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      62/*+*/, 99,      99,      99,      63/*/ */,

        52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,

        60/*8*/, 61/*9*/, 99,      99,      99,      99,      99,      99,

        99,       0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/,

        7/*H*/,  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,

        15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,

        23/*X*/, 24/*Y*/, 25/*Z*/, 99,      99,      99,      99,      99,

        99,      26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,

        33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,

        41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,

        49/*x*/, 50/*y*/, 51/*z*/, 99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99

    };

    static const char kWebSafeBase64DecodeChars[] = {

        // This array was generated by the following code:

        // #include <sys/time.h>

        // #include <stdlib.h>

        // #include <string.h>

        // main()

        // {

        //   static const char Base64[] =

        //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

        //   char *pos;

        //   int idx, i, j;

        //   printf("    ");

        //   for (i = 0; i < 255; i += 8) {

        //     for (j = i; j < i + 8; j++) {

        //       pos = strchr(Base64, j);

        //       if ((pos == NULL) || (j == 0))

        //         idx = 99;

        //       else

        //         idx = pos - Base64;

        //       if (idx == 99)

        //         printf(" %2d,     ", idx);

        //       else

        //         printf(" %2d/*%c*/,", idx, j);

        //     }

        //     printf("     ");

        //   }

        // }

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      62/*-*/, 99,      99,

        52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,

        60/*8*/, 61/*9*/, 99,      99,      99,      99,      99,      99,

        99,       0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/,

        7/*H*/,  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,

        15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,

        23/*X*/, 24/*Y*/, 25/*Z*/, 99,      99,      99,      99,      63/*_*/,

        99,      26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,

        33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,

        41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,

        49/*x*/, 50/*y*/, 51/*z*/, 99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99,

        99,      99,      99,      99,      99,      99,      99,      99

    };

    // Tests a character to see if it's a whitespace character.

    //

    // Returns:

    //   YES if the character is a whitespace character.

    //   NO if the character is not a whitespace character.

    //

    GTM_INLINE BOOL IsSpace(unsigned char c) {

        // we use our own mapping here because we don't want anything w/ locale

        // support.

        static BOOL kSpaces[256] = {

            0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  // 0-9

            1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 10-19

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 20-29

            0, 0, 1, 0, 0, 0, 0, 0, 0, 0,  // 30-39

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 40-49

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 50-59

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 60-69

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 70-79

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 80-89

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 90-99

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 100-109

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 110-119

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 120-129

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 130-139

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 140-149

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 150-159

            1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 160-169

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 170-179

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 180-189

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 190-199

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 200-209

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 210-219

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 220-229

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 230-239

            0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 240-249

            0, 0, 0, 0, 0, 1,              // 250-255

        };

        return kSpaces[c];

    }

    // Calculate how long the data will be once it's base64 encoded.

    //

    // Returns:

    //   The guessed encoded length for a source length

    //

    GTM_INLINE NSUInteger CalcEncodedLength(NSUInteger srcLen, BOOL padded) {

        NSUInteger intermediate_result = 8 * srcLen + 5;

        NSUInteger len = intermediate_result / 6;

        if (padded) {

            len = ((len + 3) / 4) * 4;

        }

        return len;

    }

    // Tries to calculate how long the data will be once it's base64 decoded.

    // Unlike the above, this is always an upperbound, since the source data

    // could have spaces and might end with the padding characters on them.

    //

    // Returns:

    //   The guessed decoded length for a source length

    //

    GTM_INLINE NSUInteger GuessDecodedLength(NSUInteger srcLen) {

        return (srcLen + 3) / 4 * 3;

    }

    @interface GTMBase64 (PrivateMethods)

    +(NSData *)baseEncode:(const void *)bytes

                   length:(NSUInteger)length

                  charset:(const char *)charset

                   padded:(BOOL)padded;

    +(NSData *)baseDecode:(const void *)bytes

                   length:(NSUInteger)length

                  charset:(const char*)charset

           requirePadding:(BOOL)requirePadding;

    +(NSUInteger)baseEncode:(const char *)srcBytes

                     srcLen:(NSUInteger)srcLen

                  destBytes:(char *)destBytes

                    destLen:(NSUInteger)destLen

                    charset:(const char *)charset

                     padded:(BOOL)padded;

    +(NSUInteger)baseDecode:(const char *)srcBytes

                     srcLen:(NSUInteger)srcLen

                  destBytes:(char *)destBytes

                    destLen:(NSUInteger)destLen

                    charset:(const char *)charset

             requirePadding:(BOOL)requirePadding;

    @end

    @implementation GTMBase64

    //

    // Standard Base64 (RFC) handling

    //

    +(NSData *)encodeData:(NSData *)data {

        return [self baseEncode:[data bytes]

                         length:[data length]

                        charset:kBase64EncodeChars

                         padded:YES];

    }

    +(NSData *)decodeData:(NSData *)data {

        return [self baseDecode:[data bytes]

                         length:[data length]

                        charset:kBase64DecodeChars

                 requirePadding:YES];

    }

    +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length {

        return [self baseEncode:bytes

                         length:length

                        charset:kBase64EncodeChars

                         padded:YES];

    }

    +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length {

        return [self baseDecode:bytes

                         length:length

                        charset:kBase64DecodeChars

                 requirePadding:YES];

    }

    +(NSString *)stringByEncodingData:(NSData *)data {

        NSString *result = nil;

        NSData *converted = [self baseEncode:[data bytes]

                                      length:[data length]

                                     charset:kBase64EncodeChars

                                      padded:YES];

        if (converted) {

            result = [[[NSString alloc] initWithData:converted

                                            encoding:NSASCIIStringEncoding] autorelease];

        }

        return result;

    }

    +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length {

        NSString *result = nil;

        NSData *converted = [self baseEncode:bytes

                                      length:length

                                     charset:kBase64EncodeChars

                                      padded:YES];

        if (converted) {

            result = [[[NSString alloc] initWithData:converted

                                            encoding:NSASCIIStringEncoding] autorelease];

        }

        return result;

    }

    +(NSData *)decodeString:(NSString *)string {

        NSData *result = nil;

        NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];

        if (data) {

            result = [self baseDecode:[data bytes]

                               length:[data length]

                              charset:kBase64DecodeChars

                       requirePadding:YES];

        }

        return result;

    }

    //

    // Modified Base64 encoding so the results can go onto urls.

    //

    // The changes are in the characters generated and also the result isn't

    // padded to a multiple of 4.

    // Must use the matching call to encode/decode, won't interop with the

    // RFC versions.

    //

    +(NSData *)webSafeEncodeData:(NSData *)data

                          padded:(BOOL)padded {

        return [self baseEncode:[data bytes]

                         length:[data length]

                        charset:kWebSafeBase64EncodeChars

                         padded:padded];

    }

    +(NSData *)webSafeDecodeData:(NSData *)data {

        return [self baseDecode:[data bytes]

                         length:[data length]

                        charset:kWebSafeBase64DecodeChars

                 requirePadding:NO];

    }

    +(NSData *)webSafeEncodeBytes:(const void *)bytes

                           length:(NSUInteger)length

                           padded:(BOOL)padded {

        return [self baseEncode:bytes

                         length:length

                        charset:kWebSafeBase64EncodeChars

                         padded:padded];

    }

    +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length {

        return [self baseDecode:bytes

                         length:length

                        charset:kWebSafeBase64DecodeChars

                 requirePadding:NO];

    }

    +(NSString *)stringByWebSafeEncodingData:(NSData *)data

                                      padded:(BOOL)padded {

        NSString *result = nil;

        NSData *converted = [self baseEncode:[data bytes]

                                      length:[data length]

                                     charset:kWebSafeBase64EncodeChars

                                      padded:padded];

        if (converted) {

            result = [[[NSString alloc] initWithData:converted

                                            encoding:NSASCIIStringEncoding] autorelease];

        }

        return result;

    }

    +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes

                                       length:(NSUInteger)length

                                       padded:(BOOL)padded {

        NSString *result = nil;

        NSData *converted = [self baseEncode:bytes

                                      length:length

                                     charset:kWebSafeBase64EncodeChars

                                      padded:padded];

        if (converted) {

            result = [[[NSString alloc] initWithData:converted

                                            encoding:NSASCIIStringEncoding] autorelease];

        }

        return result;

    }

    +(NSData *)webSafeDecodeString:(NSString *)string {

        NSData *result = nil;

        NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];

        if (data) {

            result = [self baseDecode:[data bytes]

                               length:[data length]

                              charset:kWebSafeBase64DecodeChars

                       requirePadding:NO];

        }

        return result;

    }

    @end

    @implementation GTMBase64 (PrivateMethods)

    //

    // baseEncode:length:charset:padded:

    //

    // Does the common lifting of creating the dest NSData.  it creates & sizes the

    // data for the results.  |charset| is the characters to use for the encoding

    // of the data.  |padding| controls if the encoded data should be padded to a

    // multiple of 4.

    //

    // Returns:

    //   an autorelease NSData with the encoded data, nil if any error.

    //

    +(NSData *)baseEncode:(const void *)bytes

                   length:(NSUInteger)length

                  charset:(const char *)charset

                   padded:(BOOL)padded {

        // how big could it be?

        NSUInteger maxLength = CalcEncodedLength(length, padded);

        // make space

        NSMutableData *result = [NSMutableData data];

        [result setLength:maxLength];

        // do it

        NSUInteger finalLength = [self baseEncode:bytes

                                           srcLen:length

                                        destBytes:[result mutableBytes]

                                          destLen:[result length]

                                          charset:charset

                                           padded:padded];

        if (finalLength) {

            _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?");

        } else {

            // shouldn't happen, this means we ran out of space

            result = nil;

        }

        return result;

    }

    //

    // baseDecode:length:charset:requirePadding:

    //

    // Does the common lifting of creating the dest NSData.  it creates & sizes the

    // data for the results.  |charset| is the characters to use for the decoding

    // of the data.

    //

    // Returns:

    //   an autorelease NSData with the decoded data, nil if any error.

    //

    //

    +(NSData *)baseDecode:(const void *)bytes

                   length:(NSUInteger)length

                  charset:(const char *)charset

           requirePadding:(BOOL)requirePadding {

        // could try to calculate what it will end up as

        NSUInteger maxLength = GuessDecodedLength(length);

        // make space

        NSMutableData *result = [NSMutableData data];

        [result setLength:maxLength];

        // do it

        NSUInteger finalLength = [self baseDecode:bytes

                                           srcLen:length

                                        destBytes:[result mutableBytes]

                                          destLen:[result length]

                                          charset:charset

                                   requirePadding:requirePadding];

        if (finalLength) {

            if (finalLength != maxLength) {

                // resize down to how big it was

                [result setLength:finalLength];

            }

        } else {

            // either an error in the args, or we ran out of space

            result = nil;

        }

        return result;

    }

    //

    // baseEncode:srcLen:destBytes:destLen:charset:padded:

    //

    // Encodes the buffer into the larger.  returns the length of the encoded

    // data, or zero for an error.

    // |charset| is the characters to use for the encoding

    // |padded| tells if the result should be padded to a multiple of 4.

    //

    // Returns:

    //   the length of the encoded data.  zero if any error.

    //

    +(NSUInteger)baseEncode:(const char *)srcBytes

                     srcLen:(NSUInteger)srcLen

                  destBytes:(char *)destBytes

                    destLen:(NSUInteger)destLen

                    charset:(const char *)charset

                     padded:(BOOL)padded {

        if (!srcLen || !destLen || !srcBytes || !destBytes) {

            return 0;

        }

        

        char *curDest = destBytes;

        const unsigned char *curSrc = (const unsigned char *)(srcBytes);

        

        // Three bytes of data encodes to four characters of cyphertext.

        // So we can pump through three-byte chunks atomically.

        while (srcLen > 2) {

            // space?

            _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");

            curDest[0] = charset[curSrc[0] >> 2];

            curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];

            curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)];

            curDest[3] = charset[curSrc[2] & 0x3f];

            

            curDest += 4;

            curSrc += 3;

            srcLen -= 3;

            destLen -= 4;

        }

        

        // now deal with the tail (<=2 bytes)

        switch (srcLen) {

            case 0:

                // Nothing left; nothing more to do.

                break;

            case 1:

                // One byte left: this encodes to two characters, and (optionally)

                // two pad characters to round out the four-character cypherblock.

                _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");

                curDest[0] = charset[curSrc[0] >> 2];

                curDest[1] = charset[(curSrc[0] & 0x03) << 4];

                curDest += 2;

                if (padded) {

                    _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");

                    curDest[0] = kBase64PaddingChar;

                    curDest[1] = kBase64PaddingChar;

                    curDest += 2;

                }

                break;

            case 2:

                // Two bytes left: this encodes to three characters, and (optionally)

                // one pad character to round out the four-character cypherblock.

                _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong");

                curDest[0] = charset[curSrc[0] >> 2];

                curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];

                curDest[2] = charset[(curSrc[1] & 0x0f) << 2];

                curDest += 3;

                if (padded) {

                    _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");

                    curDest[0] = kBase64PaddingChar;

                    curDest += 1;

                }

                break;

        }

        // return the length

        return (curDest - destBytes);

    }

    //

    // baseDecode:srcLen:destBytes:destLen:charset:requirePadding:

    //

    // Decodes the buffer into the larger.  returns the length of the decoded

    // data, or zero for an error.

    // |charset| is the character decoding buffer to use

    //

    // Returns:

    //   the length of the encoded data.  zero if any error.

    //

    +(NSUInteger)baseDecode:(const char *)srcBytes

                     srcLen:(NSUInteger)srcLen

                  destBytes:(char *)destBytes

                    destLen:(NSUInteger)destLen

                    charset:(const char *)charset

             requirePadding:(BOOL)requirePadding {

        if (!srcLen || !destLen || !srcBytes || !destBytes) {

            return 0;

        }

        

        int decode;

        NSUInteger destIndex = 0;

        int state = 0;

        char ch = 0;

        while (srcLen-- && (ch = *srcBytes++) != 0)  {

            if (IsSpace(ch))  // Skip whitespace

                continue;

            

            if (ch == kBase64PaddingChar)

                break;

            

            decode = charset[(unsigned int)ch];

            if (decode == kBase64InvalidChar)

                return 0;

            

            // Four cyphertext characters decode to three bytes.

            // Therefore we can be in one of four states.

            switch (state) {

                case 0:

                    // We're at the beginning of a four-character cyphertext block.

                    // This sets the high six bits of the first byte of the

                    // plaintext block.

                    _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");

                    destBytes[destIndex] = decode << 2;

                    state = 1;

                    break;

                case 1:

                    // We're one character into a four-character cyphertext block.

                    // This sets the low two bits of the first plaintext byte,

                    // and the high four bits of the second plaintext byte.

                    _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");

                    destBytes[destIndex] |= decode >> 4;

                    destBytes[destIndex+1] = (decode & 0x0f) << 4;

                    destIndex++;

                    state = 2;

                    break;

                case 2:

                    // We're two characters into a four-character cyphertext block.

                    // This sets the low four bits of the second plaintext

                    // byte, and the high two bits of the third plaintext byte.

                    // However, if this is the end of data, and those two

                    // bits are zero, it could be that those two bits are

                    // leftovers from the encoding of data that had a length

                    // of two mod three.

                    _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");

                    destBytes[destIndex] |= decode >> 2;

                    destBytes[destIndex+1] = (decode & 0x03) << 6;

                    destIndex++;

                    state = 3;

                    break;

                case 3:

                    // We're at the last character of a four-character cyphertext block.

                    // This sets the low six bits of the third plaintext byte.

                    _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");

                    destBytes[destIndex] |= decode;

                    destIndex++;

                    state = 0;

                    break;

            }

        }

        

        // We are done decoding Base-64 chars.  Let's see if we ended

        //      on a byte boundary, and/or with erroneous trailing characters.

        if (ch == kBase64PaddingChar) {               // We got a pad char

            if ((state == 0) || (state == 1)) {

                return 0;  // Invalid '=' in first or second position

            }

            if (srcLen == 0) {

                if (state == 2) { // We run out of input but we still need another '='

                    return 0;

                }

                // Otherwise, we are in state 3 and only need this '='

            } else {

                if (state == 2) {  // need another '='

                    while ((ch = *srcBytes++) && (srcLen-- > 0)) {

                        if (!IsSpace(ch))

                            break;

                    }

                    if (ch != kBase64PaddingChar) {

                        return 0;

                    }

                }

                // state = 1 or 2, check if all remain padding is space

                while ((ch = *srcBytes++) && (srcLen-- > 0)) {

                    if (!IsSpace(ch)) {

                        return 0;

                    }

                }

            }

        } else {

            // We ended by seeing the end of the string.

            

            if (requirePadding) {

                // If we require padding, then anything but state 0 is an error.

                if (state != 0) {

                    return 0;

                }

            } else {

                // Make sure we have no partial bytes lying around.  Note that we do not

                // require trailing '=', so states 2 and 3 are okay too.

                if (state == 1) {

                    return 0;

                }

            }

        }

        

        // If then next piece of output was valid and got written to it means we got a

        // very carefully crafted input that appeared valid but contains some trailing

        // bits past the real length, so just toss the thing.

        if ((destIndex < destLen) &&

            (destBytes[destIndex] != 0)) {

            return 0;

        }

        

        return destIndex;

    }

    @end

    // GTMDefines.h

    #include <AvailabilityMacros.h>

    #include <TargetConditionals.h>

    #if TARGET_OS_IPHONE

    #include <Availability.h>

    #endif //  TARGET_OS_IPHONE

    // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs

    #ifndef MAC_OS_X_VERSION_10_5

    #define MAC_OS_X_VERSION_10_5 1050

    #endif

    #ifndef MAC_OS_X_VERSION_10_6

    #define MAC_OS_X_VERSION_10_6 1060

    #endif

    // Not all __IPHONE_X macros defined in past SDKs

    #ifndef __IPHONE_2_1

    #define __IPHONE_2_1 20100

    #endif

    #ifndef __IPHONE_2_2

    #define __IPHONE_2_2 20200

    #endif

    #ifndef __IPHONE_3_0

    #define __IPHONE_3_0 30000

    #endif

    #ifndef __IPHONE_3_1

    #define __IPHONE_3_1 30100

    #endif

    #ifndef __IPHONE_3_2

    #define __IPHONE_3_2 30200

    #endif

    #ifndef __IPHONE_4_0

    #define __IPHONE_4_0 40000

    #endif

    // ----------------------------------------------------------------------------

    // CPP symbols that can be overridden in a prefix to control how the toolbox

    // is compiled.

    // ----------------------------------------------------------------------------

    // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and

    // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens

    // when a validation fails. If you implement your own validators, you may want

    // to control their internals using the same macros for consistency.

    #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT

    #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0

    #endif

    // Give ourselves a consistent way to do inlines.  Apple's macros even use

    // a few different actual definitions, so we're based off of the foundation

    // one.

    #if !defined(GTM_INLINE)

    #if defined (__GNUC__) && (__GNUC__ == 4)

    #define GTM_INLINE static __inline__ __attribute__((always_inline))

    #else

    #define GTM_INLINE static __inline__

    #endif

    #endif

    // Give ourselves a consistent way of doing externs that links up nicely

    // when mixing objc and objc++

    #if !defined (GTM_EXTERN)

    #if defined __cplusplus

    #define GTM_EXTERN extern "C"

    #define GTM_EXTERN_C_BEGIN extern "C" {

    #define GTM_EXTERN_C_END }

    #else

    #define GTM_EXTERN extern

    #define GTM_EXTERN_C_BEGIN

    #define GTM_EXTERN_C_END

    #endif

    #endif

    // Give ourselves a consistent way of exporting things if we have visibility

    // set to hidden.

    #if !defined (GTM_EXPORT)

    #define GTM_EXPORT __attribute__((visibility("default")))

    #endif

    // Give ourselves a consistent way of declaring something as unused. This

    // doesn't use __unused because that is only supported in gcc 4.2 and greater.

    #if !defined (GTM_UNUSED)

    #define GTM_UNUSED(x) ((void)(x))

    #endif

    // _GTMDevLog & _GTMDevAssert

    //

    // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for

    // developer level errors.  This implementation simply macros to NSLog/NSAssert.

    // It is not intended to be a general logging/reporting system.

    //

    // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert

    // for a little more background on the usage of these macros.

    //

    //    _GTMDevLog           log some error/problem in debug builds

    //    _GTMDevAssert        assert if conditon isn't met w/in a method/function

    //                           in all builds.

    //

    // To replace this system, just provide different macro definitions in your

    // prefix header.  Remember, any implementation you provide *must* be thread

    // safe since this could be called by anything in what ever situtation it has

    // been placed in.

    //

    // We only define the simple macros if nothing else has defined this.

    #ifndef _GTMDevLog

    #ifdef DEBUG

    #define _GTMDevLog(...) NSLog(__VA_ARGS__)

    #else

    #define _GTMDevLog(...) do { } while (0)

    #endif

    #endif // _GTMDevLog

    #ifndef _GTMDevAssert

    // we directly invoke the NSAssert handler so we can pass on the varargs

    // (NSAssert doesn't have a macro we can use that takes varargs)

    #if !defined(NS_BLOCK_ASSERTIONS)

    #define _GTMDevAssert(condition, ...)                                      

    do {                                                                     

    if (!(condition)) {                                                    

    [[NSAssertionHandler currentHandler]                                 

    handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__]

    file:[NSString stringWithUTF8String:__FILE__] 

    lineNumber:__LINE__                                 

    description:__VA_ARGS__];                            

    }                                                                      

    } while(0)

    #else // !defined(NS_BLOCK_ASSERTIONS)

    #define _GTMDevAssert(condition, ...) do { } while (0)

    #endif // !defined(NS_BLOCK_ASSERTIONS)

    #endif // _GTMDevAssert

    // _GTMCompileAssert

    // _GTMCompileAssert is an assert that is meant to fire at compile time if you

    // want to check things at compile instead of runtime. For example if you

    // want to check that a wchar is 4 bytes instead of 2 you would use

    // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)

    // Note that the second "arg" is not in quotes, and must be a valid processor

    // symbol in it's own right (no spaces, punctuation etc).

    // Wrapping this in an #ifndef allows external groups to define their own

    // compile time assert scheme.

    #ifndef _GTMCompileAssert

    // We got this technique from here:

    // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html

    #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg

    #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)

    #define _GTMCompileAssert(test, msg)

    typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]

    #endif // _GTMCompileAssert

    // ----------------------------------------------------------------------------

    // CPP symbols defined based on the project settings so the GTM code has

    // simple things to test against w/o scattering the knowledge of project

    // setting through all the code.

    // ----------------------------------------------------------------------------

    // Provide a single constant CPP symbol that all of GTM uses for ifdefing

    // iPhone code.

    #if TARGET_OS_IPHONE // iPhone SDK

    // For iPhone specific stuff

    #define GTM_IPHONE_SDK 1

    #if TARGET_IPHONE_SIMULATOR

    #define GTM_IPHONE_SIMULATOR 1

    #else

    #define GTM_IPHONE_DEVICE 1

    #endif  // TARGET_IPHONE_SIMULATOR

    #else

    // For MacOS specific stuff

    #define GTM_MACOS_SDK 1

    #endif

    // Some of our own availability macros

    #if GTM_MACOS_SDK

    #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE

    #define GTM_AVAILABLE_ONLY_ON_MACOS

    #else

    #define GTM_AVAILABLE_ONLY_ON_IPHONE

    #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE

    #endif

    // Provide a symbol to include/exclude extra code for GC support.  (This mainly

    // just controls the inclusion of finalize methods).

    #ifndef GTM_SUPPORT_GC

    #if GTM_IPHONE_SDK

    // iPhone never needs GC

    #define GTM_SUPPORT_GC 0

    #else

    // We can't find a symbol to tell if GC is supported/required, so best we

    // do on Mac targets is include it if we're on 10.5 or later.

    #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5

    #define GTM_SUPPORT_GC 0

    #else

    #define GTM_SUPPORT_GC 1

    #endif

    #endif

    #endif

    // To simplify support for 64bit (and Leopard in general), we provide the type

    // defines for non Leopard SDKs

    #if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)

    // NSInteger/NSUInteger and Max/Mins

    #ifndef NSINTEGER_DEFINED

    #if __LP64__ || NS_BUILD_32_LIKE_64

    typedef long NSInteger;

    typedef unsigned long NSUInteger;

    #else

    typedef int NSInteger;

    typedef unsigned int NSUInteger;

    #endif

    #define NSIntegerMax    LONG_MAX

    #define NSIntegerMin    LONG_MIN

    #define NSUIntegerMax   ULONG_MAX

    #define NSINTEGER_DEFINED 1

    #endif  // NSINTEGER_DEFINED

    // CGFloat

    #ifndef CGFLOAT_DEFINED

    #if defined(__LP64__) && __LP64__

    // This really is an untested path (64bit on Tiger?)

    typedef double CGFloat;

    #define CGFLOAT_MIN DBL_MIN

    #define CGFLOAT_MAX DBL_MAX

    #define CGFLOAT_IS_DOUBLE 1

    #else /* !defined(__LP64__) || !__LP64__ */

    typedef float CGFloat;

    #define CGFLOAT_MIN FLT_MIN

    #define CGFLOAT_MAX FLT_MAX

    #define CGFLOAT_IS_DOUBLE 0

    #endif /* !defined(__LP64__) || !__LP64__ */

    #define CGFLOAT_DEFINED 1

    #endif // CGFLOAT_DEFINED

    #endif  // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5

    // Some support for advanced clang static analysis functionality

    // See http://clang-analyzer.llvm.org/annotations.html

    #ifndef __has_feature      // Optional.

    #define __has_feature(x) 0 // Compatibility with non-clang compilers.

    #endif

    #ifndef NS_RETURNS_RETAINED

    #if __has_feature(attribute_ns_returns_retained)

    #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))

    #else

    #define NS_RETURNS_RETAINED

    #endif

    #endif

    #ifndef NS_RETURNS_NOT_RETAINED

    #if __has_feature(attribute_ns_returns_not_retained)

    #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

    #else

    #define NS_RETURNS_NOT_RETAINED

    #endif

    #endif

    #ifndef CF_RETURNS_RETAINED

    #if __has_feature(attribute_cf_returns_retained)

    #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))

    #else

    #define CF_RETURNS_RETAINED

    #endif

    #endif

    #ifndef CF_RETURNS_NOT_RETAINED

    #if __has_feature(attribute_cf_returns_not_retained)

    #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))

    #else

    #define CF_RETURNS_NOT_RETAINED

    #endif

    #endif

    // Defined on 10.6 and above.

    #ifndef NS_FORMAT_ARGUMENT

    #define NS_FORMAT_ARGUMENT(A)

    #endif

    // Defined on 10.6 and above.

    #ifndef NS_FORMAT_FUNCTION

    #define NS_FORMAT_FUNCTION(F,A)

    #endif

    // Defined on 10.6 and above.

    #ifndef CF_FORMAT_ARGUMENT

    #define CF_FORMAT_ARGUMENT(A)

    #endif

    // Defined on 10.6 and above.

    #ifndef CF_FORMAT_FUNCTION

    #define CF_FORMAT_FUNCTION(F,A)

    #endif

    #ifndef GTM_NONNULL

    #define GTM_NONNULL(x) __attribute__((nonnull(x)))

    #endif

    #ifdef __OBJC__

    // Declared here so that it can easily be used for logging tracking if

    // necessary. See GTMUnitTestDevLog.h for details.

    @class NSString;

    GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);

    // Macro to allow you to create NSStrings out of other macros.

    // #define FOO foo

    // NSString *fooString = GTM_NSSTRINGIFY(FOO);

    #if !defined (GTM_NSSTRINGIFY)

    #define GTM_NSSTRINGIFY_INNER(x) @#x

    #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)

    #endif

    // Macro to allow fast enumeration when building for 10.5 or later, and

    // reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration

    // does keys, so pick the right thing, nothing is done on the FastEnumeration

    // side to be sure you're getting what you wanted.

    #ifndef GTM_FOREACH_OBJECT

    #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)

    #define GTM_FOREACH_ENUMEREE(element, enumeration)

    for (element in enumeration)

    #define GTM_FOREACH_OBJECT(element, collection)

    for (element in collection)

    #define GTM_FOREACH_KEY(element, collection)

    for (element in collection)

    #else

    #define GTM_FOREACH_ENUMEREE(element, enumeration)

    for (NSEnumerator *_ ## element ## _enum = enumeration;

    (element = [_ ## element ## _enum nextObject]) != nil; )

    #define GTM_FOREACH_OBJECT(element, collection)

    GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])

    #define GTM_FOREACH_KEY(element, collection)

    GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])

    #endif

    #endif

    // ============================================================================

    // To simplify support for both Leopard and Snow Leopard we declare

    // the Snow Leopard protocols that we need here.

    #if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)

    #define GTM_10_6_PROTOCOLS_DEFINED 1

    @protocol NSConnectionDelegate

    @end

    @protocol NSAnimationDelegate

    @end

    @protocol NSImageDelegate

    @end

    @protocol NSTabViewDelegate

    @end

    #endif  // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)

    // GTM_SEL_STRING is for specifying selector (usually property) names to KVC

    // or KVO methods.

    // In debug it will generate warnings for undeclared selectors if

    // -Wunknown-selector is turned on.

    // In release it will have no runtime overhead.

    #ifndef GTM_SEL_STRING

    #ifdef DEBUG

    #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))

    #else

    #define GTM_SEL_STRING(selName) @#selName

    #endif  // DEBUG

    #endif  // GTM_SEL_STRING

    #endif // __OBJC__

    玩了哦

  • 相关阅读:
    HDU 1301 Jungle Roads (最小生成树)
    POJ 1733 Parity game (并查集)
    HDU 3038 How Many Answers Are Wrong (并查集)
    CentOS用yum安装搭建LAMP
    Linux下php安装Redis扩展
    PHPExcel用法
    利用phpmailer类邮件发送
    Vim编辑器配置
    vhost文件设置
    ThinkPHP验证码类
  • 原文地址:https://www.cnblogs.com/liuting-1204/p/6554584.html
Copyright © 2011-2022 走看看