2016-04-11 16:07:19 bitcser 阅读数 642
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7585 人正在学习 去看看 李文瀚

利用GTMBase64.h    GTMBase64.m   GTMDefines.h这个三个类   

本地图片加密

    UIImage *image = [UIImage imageNamed:@"6879FB1B-8E77-4B74-9738-D2958F644007.png"];

    NSData *data = UIImageJPEGRepresentation(image, 1.0f);

    NSData *imageData1 = [GTMBase64 encodeData:data];

    NSString *str = [[NSString alloc]initWithData:imageData1 encoding:NSASCIIStringEncoding];

    NSLog(@"%@",str);

一般情况下这个String就是后台需要的,当参数传进去就可以了

如果是选中的图片替换对应的image就可以了

图片解密的方法

    NSString *imagePath = [NSHomeDirectory() stringByAppendingFormat:@"/Documents/bronze/download/img_0_0_0.png"];
    

   NSData *data = [NSData dataWithContentsOfFile:imagePath];
    将获取到的data进行解密
  NSData *data1 = [GTMBase64 decodeData:data]; UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 20, 300, 400)]; imageView.image = [UIImage imageWithData:data1]; imageView.backgroundColor = [UIColor redColor]; [self.view addSubview:imageView];
复制代码


2016-02-29 22:15:30 Cloud_Pro 阅读数 1228
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7585 人正在学习 去看看 李文瀚

为NSString写分类

NSString+Base64After3DES

.h文件

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>

@interface NSString (Base64After3DES)

/**
 *  3DES加密并转Base64
 *
 *  @param plainText        要加密的字符串
 *  @param encryptOrDecrypt 系统固定参数: kCCEncrypt
 *  @param key              自己设定的秘钥
 *
 *  @return 3DES加密后并转Base64的字符串
 */
+ (NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key; // 这个分类需要注意-fno-objc-arc的问题(需要给这个分类的.m和GTMBase64.m添加)

@end

.m文件

#import "NSString+Base64After3DES.h"
#import "GTMBase64.h"

@implementation NSString (Base64After3DES)

+(NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt key:(NSString*)key
{
    const void *vplainText;
    size_t plainTextBufferSize;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        //解密
        NSData *EncryptData = [GTMBase64 decodeData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
        plainTextBufferSize = [EncryptData length];
        vplainText = [EncryptData bytes];
    }
    else
    {
        //加密
        NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        plainTextBufferSize = [data length];
        vplainText = (const void *)[data bytes];
    }
    
    CCCryptorStatus ccStatus;
    uint8_t *bufferPtr = NULL;
    size_t bufferPtrSize = 0;
    size_t movedBytes = 0;
    
    bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    memset((void *)bufferPtr, 0x0, bufferPtrSize);
    // memset((void *) iv, 0x0, (size_t) sizeof(iv));
    
    const void *vkey = (const void *)[key UTF8String];
    // NSString *initVec = @"init Vec";
    //const void *vinitVec = (const void *) [initVec UTF8String];
    //  Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
    ccStatus = CCCrypt(encryptOrDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding | kCCOptionECBMode,
                       vkey,
                       kCCKeySize3DES,
                       nil,
                       vplainText,
                       plainTextBufferSize,
                       (void *)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    //if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
    /*else if (ccStatus == kCC ParamError) return @"PARAM ERROR";
     else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
     else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
     else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
     else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
     else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED"; */
    
    NSString *result;
    
    if (encryptOrDecrypt == kCCDecrypt)
    {
        result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
                                                                length:(NSUInteger)movedBytes]
                                        encoding:NSUTF8StringEncoding]
                  autorelease];
    }
    else
    {
        NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
        result = [GTMBase64 stringByEncodingData:myData];
    }
    
    return result;
}


@end


GTMBase64可以在GitHub上搜索下载到

在main方法里使用

#import <Foundation/Foundation.h>
#import "NSString+Base64After3DES.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString *idenStr = [NSString TripleDES:@"test" encryptOrDecrypt:kCCEncrypt key:@"key"];
        NSLog(@"%@", idenStr);
    }
    return 0;
}

这个在main方法里使用, 是我在测试的时候用的Command Line Tool测试用的, 不是在项目的main方法里面使用.  在需要的地方使用这句话就可以


2014-11-27 11:03:00 gf771115 阅读数 7325
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7585 人正在学习 去看看 李文瀚

转自:http://www.cnblogs.com/ygm900/archive/2013/05/15/3079278.html

在使用过程中,直接将被类引入到项目中即可,不需要其它辅助类。

使用示例:  将此通用类的头文件引入到目标类后,直接使用类名进行调用即可。

    NSString *str = [NSString stringWithFormat:@"YWE="];
    NSString *str1 = [NSString stringWithFormat:@"aa"];
    NSLog(@"resultStr========%@",[CommonFunc textFromBase64String:str]);   //使用类名进行调用
    NSLog(@"resultStr=========%@",[CommonFunc base64StringFromText:str1]);  //使用类名进行调用

 

源码下载: 

 

在项目中遇到字符串的base64编解码,分享一下工具类:

CommonFunc.h

复制代码
//  
//  CommonFunc.h  
//  PRJ_base64  
//  
//  Created by wangzhipeng on 12-11-29.  
//  Copyright (c) 2012年 com.comsoft. All rights reserved.  
//  
  
#import <Foundation/Foundation.h>  
  
#define __BASE64( text )        [CommonFunc base64StringFromText:text]  
#define __TEXT( base64 )        [CommonFunc textFromBase64String:base64]  
  
@interface CommonFunc : NSObject  
  
/****************************************************************************** 
 函数名称 : + (NSString *)base64StringFromText:(NSString *)text 
 函数描述 : 将文本转换为base64格式字符串 
 输入参数 : (NSString *)text    文本 
 输出参数 : N/A 
 返回参数 : (NSString *)    base64格式字符串 
 备注信息 : 
 ******************************************************************************/  
+ (NSString *)base64StringFromText:(NSString *)text;  
  
/****************************************************************************** 
 函数名称 : + (NSString *)textFromBase64String:(NSString *)base64 
 函数描述 : 将base64格式字符串转换为文本 
 输入参数 : (NSString *)base64  base64格式字符串 
 输出参数 : N/A 
 返回参数 : (NSString *)    文本 
 备注信息 : 
 ******************************************************************************/  
+ (NSString *)textFromBase64String:(NSString *)base64;  
  
@end 
复制代码

CommonFunc.m

复制代码
//  
//  CommonFunc.m  
//  PRJ_base64  
//  
//  Created by wangzhipeng on 12-11-29.  
//  Copyright (c) 2012年 com.comsoft. All rights reserved.  
//  
  
#import "CommonFunc.h"  
  
//引入IOS自带密码库  
#import <CommonCrypto/CommonCryptor.h>  
  
//空字符串  
#define     LocalStr_None           @""  
  
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  
@implementation CommonFunc  
  
+ (NSString *)base64StringFromText:(NSString *)text  
{  
    if (text && ![text isEqualToString:LocalStr_None]) {  
        //取项目的bundleIdentifier作为KEY  改动了此处
        //NSString *key = [[NSBundle mainBundle] bundleIdentifier];  
        NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];  
        //IOS 自带DES加密 Begin  改动了此处
        //data = [self DESEncrypt:data WithKey:key];  
        //IOS 自带DES加密 End  
        return [self base64EncodedStringFrom:data];  
    }  
    else {  
        return LocalStr_None;  
    }  
}  
  
+ (NSString *)textFromBase64String:(NSString *)base64  
{  
    if (base64 && ![base64 isEqualToString:LocalStr_None]) {  
        //取项目的bundleIdentifier作为KEY   改动了此处
        //NSString *key = [[NSBundle mainBundle] bundleIdentifier];  
        NSData *data = [self dataWithBase64EncodedString:base64];  
        //IOS 自带DES解密 Begin    改动了此处
        //data = [self DESDecrypt:data WithKey:key];    
        //IOS 自带DES加密 End  
        return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];  
    }  
    else {  
        return LocalStr_None;  
    }  
}  
  
/****************************************************************************** 
 函数名称 : + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key 
 函数描述 : 文本数据进行DES加密 
 输入参数 : (NSData *)data     
          (NSString *)key 
 输出参数 : N/A 
 返回参数 : (NSData *) 
 备注信息 : 此函数不可用于过长文本 
 ******************************************************************************/  
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key  
{  
    char keyPtr[kCCKeySizeAES256+1];  
    bzero(keyPtr, sizeof(keyPtr));  
      
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
      
    NSUInteger dataLength = [data length];  
      
    size_t bufferSize = dataLength + kCCBlockSizeAES128;  
    void *buffer = malloc(bufferSize);  
      
    size_t numBytesEncrypted = 0;  
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,  
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,  
                                          keyPtr, kCCBlockSizeDES,  
                                          NULL,  
                                          [data bytes], dataLength,  
                                          buffer, bufferSize,  
                                          &numBytesEncrypted);  
    if (cryptStatus == kCCSuccess) {  
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];  
    }  
      
    free(buffer);  
    return nil;  
}  
  
/****************************************************************************** 
 函数名称 : + (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key 
 函数描述 : 文本数据进行DES解密 
 输入参数 : (NSData *)data 
          (NSString *)key 
 输出参数 : N/A 
 返回参数 : (NSData *) 
 备注信息 : 此函数不可用于过长文本 
 ******************************************************************************/  
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key  
{  
    char keyPtr[kCCKeySizeAES256+1];  
    bzero(keyPtr, sizeof(keyPtr));  
      
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];  
      
    NSUInteger dataLength = [data length];  
      
    size_t bufferSize = dataLength + kCCBlockSizeAES128;  
    void *buffer = malloc(bufferSize);  
      
    size_t numBytesDecrypted = 0;  
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,  
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,  
                                          keyPtr, kCCBlockSizeDES,  
                                          NULL,  
                                          [data bytes], dataLength,  
                                          buffer, bufferSize,  
                                          &numBytesDecrypted);  
      
    if (cryptStatus == kCCSuccess) {  
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];  
    }  
      
    free(buffer);  
    return nil;  
}  
  
/****************************************************************************** 
 函数名称 : + (NSData *)dataWithBase64EncodedString:(NSString *)string 
 函数描述 : base64格式字符串转换为文本数据 
 输入参数 : (NSString *)string 
 输出参数 : N/A 
 返回参数 : (NSData *) 
 备注信息 : 
 ******************************************************************************/  
+ (NSData *)dataWithBase64EncodedString:(NSString *)string  
{  
    if (string == nil)  
        [NSException raise:NSInvalidArgumentException format:nil];  
    if ([string length] == 0)  
        return [NSData data];  
      
    static char *decodingTable = NULL;  
    if (decodingTable == NULL)  
    {  
        decodingTable = malloc(256);  
        if (decodingTable == NULL)  
            return nil;  
        memset(decodingTable, CHAR_MAX, 256);  
        NSUInteger i;  
        for (i = 0; i < 64; i++)  
            decodingTable[(short)encodingTable[i]] = i;  
    }  
      
    const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];  
    if (characters == NULL)     //  Not an ASCII string!  
        return nil;  
    char *bytes = malloc((([string length] + 3) / 4) * 3);  
    if (bytes == NULL)  
        return nil;  
    NSUInteger length = 0;  
      
    NSUInteger i = 0;  
    while (YES)  
    {  
        char buffer[4];  
        short bufferLength;  
        for (bufferLength = 0; bufferLength < 4; i++)  
        {  
            if (characters[i] == '\0')  
                break;  
            if (isspace(characters[i]) || characters[i] == '=')  
                continue;  
            buffer[bufferLength] = decodingTable[(short)characters[i]];  
            if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!  
            {  
                free(bytes);  
                return nil;  
            }  
        }  
          
        if (bufferLength == 0)  
            break;  
        if (bufferLength == 1)      //  At least two characters are needed to produce one byte!  
        {  
            free(bytes);  
            return nil;  
        }  
          
        //  Decode the characters in the buffer to bytes.  
        bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);  
        if (bufferLength > 2)  
            bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);  
        if (bufferLength > 3)  
            bytes[length++] = (buffer[2] << 6) | buffer[3];  
    }  
      
    bytes = realloc(bytes, length);  
    return [NSData dataWithBytesNoCopy:bytes length:length];  
}  
  
/****************************************************************************** 
 函数名称 : + (NSString *)base64EncodedStringFrom:(NSData *)data 
 函数描述 : 文本数据转换为base64格式字符串 
 输入参数 : (NSData *)data 
 输出参数 : N/A 
 返回参数 : (NSString *) 
 备注信息 :  
 ******************************************************************************/  
+ (NSString *)base64EncodedStringFrom:(NSData *)data  
{  
    if ([data length] == 0)  
        return @"";  
      
    char *characters = malloc((([data length] + 2) / 3) * 4);  
    if (characters == NULL)  
        return nil;  
    NSUInteger length = 0;  
      
    NSUInteger i = 0;  
    while (i < [data length])  
    {  
        char buffer[3] = {0,0,0};  
        short bufferLength = 0;  
        while (bufferLength < 3 && i < [data length])  
            buffer[bufferLength++] = ((char *)[data bytes])[i++];  
          
        //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.  
        characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];  
        characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];  
        if (bufferLength > 1)  
            characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];  
        else characters[length++] = '=';  
        if (bufferLength > 2)  
            characters[length++] = encodingTable[buffer[2] & 0x3F];  
        else characters[length++] = '=';  
    }  
      
    return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];  
}  
  
@end  
复制代码

 

转自: http://blog.csdn.net/shencaifeixia1/article/details/8530884


2016-01-27 16:15:04 sevenquan 阅读数 1262
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7585 人正在学习 去看看 李文瀚

DES是一种分组数据加密技术(先将数据分成固定长度的小数据块,之后进行加密),速度较快,适用于大量数据加密
3DES是一种基于DES的加密算法,使用3个不同密匙对同一个分组数据块进行3次加密,如此以使得密文强度更高。
相较于DES3DES算法而言,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.   
  7. + (NSString *)decryptWithText:(NSString *)sText  
  8. {  
  9.     //kCCDecrypt 解密  
  10.     return [self encrypt:sText encryptOrDecrypt:kCCDecrypt key:@"des"];  
  11. }  
  12.   
  13. + (NSString *)encrypt:(NSString *)sText encryptOrDecrypt:(CCOperation)encryptOperation key:(NSString *)key  
  14. {  
  15.     const void *dataIn;  
  16.     size_t dataInLength;  
  17.       
  18.     if (encryptOperation == kCCDecrypt)//传递过来的是decrypt 解码  
  19.     {  
  20.         //解码 base64  
  21.         NSData *decryptData = [GTMBase64 decodeData:[sText dataUsingEncoding:NSUTF8StringEncoding]];//转成utf-8并decode  
  22.         dataInLength = [decryptData length];  
  23.         dataIn = [decryptData bytes];  
  24.     }  
  25.     else  //encrypt  
  26.     {  
  27.         NSData* encryptData = [sText dataUsingEncoding:NSUTF8StringEncoding];  
  28.         dataInLength = [encryptData length];  
  29.         dataIn = (const void *)[encryptData bytes];  
  30.     }  
  31.       
  32.     /* 
  33.      DES加密 :用CCCrypt函数加密一下,然后用base64编码下,传过去 
  34.      DES解密 :把收到的数据根据base64,decode一下,然后再用CCCrypt函数解密,得到原本的数据 
  35.      */  
  36.     CCCryptorStatus ccStatus;  
  37.     uint8_t *dataOut = NULL; //可以理解位type/typedef 的缩写(有效的维护了代码,比如:一个人用int,一个人用long。最好用typedef来定义)  
  38.     size_t dataOutAvailable = 0; //size_t  是操作符sizeof返回的结果类型  
  39.     size_t dataOutMoved = 0;  
  40.       
  41.     dataOutAvailable = (dataInLength + kCCBlockSizeDES) & ~(kCCBlockSizeDES - 1);  
  42.     dataOut = malloc( dataOutAvailable * sizeof(uint8_t));  
  43.     memset((void *)dataOut, 0x0, dataOutAvailable);//将已开辟内存空间buffer的首 1 个字节的值设为值 0  
  44.       
  45.     NSString *initIv = @"12345678";  
  46.     const void *vkey = (const void *) [key UTF8String];  
  47.     const void *iv = (const void *) [initIv UTF8String];  
  48.       
  49.     //CCCrypt函数 加密/解密  
  50.     ccStatus = CCCrypt(encryptOperation,//  加密/解密  
  51.                        kCCAlgorithmDES,//  加密根据哪个标准(des,3des,aes。。。。)  
  52.                        kCCOptionPKCS7Padding,//  选项分组密码算法(des:对每块分组加一次密  3DES:对每块分组加三个不同的密)  
  53.                        vkey,  //密钥    加密和解密的密钥必须一致  
  54.                        kCCKeySizeDES,//   DES 密钥的大小(kCCKeySizeDES=8)  
  55.                        iv, //  可选的初始矢量  
  56.                        dataIn, // 数据的存储单元  
  57.                        dataInLength,// 数据的大小  
  58.                        (void *)dataOut,// 用于返回数据  
  59.                        dataOutAvailable,  
  60.                        &dataOutMoved);  
  61.       
  62.     NSString *result = nil;  
  63.       
  64.     if (encryptOperation == kCCDecrypt)//encryptOperation==1  解码  
  65.     {  
  66.         //得到解密出来的data数据,改变为utf-8的字符串  
  67.         result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved] encoding:NSUTF8StringEncoding] autorelease];  
  68.     }  
  69.     else //encryptOperation==0  (加密过程中,把加好密的数据转成base64的)  
  70.     {  
  71.         //编码 base64  
  72.         NSData *data = [NSData dataWithBytes:(const void *)dataOut length:(NSUInteger)dataOutMoved];  
  73.         result = [GTMBase64 stringByEncodingData:data];  
  74.     }  
  75.       
  76.     return result;  
  77. }  



这里用到了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.   
  19. #import <Foundation/Foundation.h>  
  20. #import "GTMDefines.h"  
  21.   
  22. // GTMBase64  
  23. //  
  24. /// Helper for handling Base64 and WebSafeBase64 encodings  
  25. //  
  26. /// The webSafe methods use different character set and also the results aren't  
  27. /// always padded to a multiple of 4 characters.  This is done so the resulting  
  28. /// data can be used in urls and url query arguments without needing any  
  29. /// encoding.  You must use the webSafe* methods together, the data does not  
  30. /// interop with the RFC methods.  
  31. //  
  32. @interface GTMBase64 : NSObject  
  33.   
  34. //  
  35. // Standard Base64 (RFC) handling  
  36. //  
  37.   
  38. // encodeData:  
  39. //  
  40. /// Base64 encodes contents of the NSData object.  
  41. //  
  42. /// Returns:  
  43. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  44. //  
  45. +(NSData *)encodeData:(NSData *)data;  
  46.   
  47. // decodeData:  
  48. //  
  49. /// Base64 decodes contents of the NSData object.  
  50. //  
  51. /// Returns:  
  52. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  53. //  
  54. +(NSData *)decodeData:(NSData *)data;  
  55.   
  56. // encodeBytes:length:  
  57. //  
  58. /// Base64 encodes the data pointed at by |bytes|.  
  59. //  
  60. /// Returns:  
  61. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  62. //  
  63. +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length;  
  64.   
  65. // decodeBytes:length:  
  66. //  
  67. /// Base64 decodes the data pointed at by |bytes|.  
  68. //  
  69. /// Returns:  
  70. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  71. //  
  72. +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length;  
  73.   
  74. // stringByEncodingData:  
  75. //  
  76. /// Base64 encodes contents of the NSData object.  
  77. //  
  78. /// Returns:  
  79. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  80. //  
  81. +(NSString *)stringByEncodingData:(NSData *)data;  
  82.   
  83. // stringByEncodingBytes:length:  
  84. //  
  85. /// Base64 encodes the data pointed at by |bytes|.  
  86. //  
  87. /// Returns:  
  88. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  89. //  
  90. +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length;  
  91.   
  92. // decodeString:  
  93. //  
  94. /// Base64 decodes contents of the NSString.  
  95. //  
  96. /// Returns:  
  97. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  98. //  
  99. +(NSData *)decodeString:(NSString *)string;  
  100.   
  101. //  
  102. // Modified Base64 encoding so the results can go onto urls.  
  103. //  
  104. // The changes are in the characters generated and also allows the result to  
  105. // not be padded to a multiple of 4.  
  106. // Must use the matching call to encode/decode, won't interop with the  
  107. // RFC versions.  
  108. //  
  109.   
  110. // webSafeEncodeData:padded:  
  111. //  
  112. /// WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES  
  113. /// then padding characters are added so the result length is a multiple of 4.  
  114. //  
  115. /// Returns:  
  116. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  117. //  
  118. +(NSData *)webSafeEncodeData:(NSData *)data  
  119.                       padded:(BOOL)padded;  
  120.   
  121. // webSafeDecodeData:  
  122. //  
  123. /// WebSafe Base64 decodes contents of the NSData object.  
  124. //  
  125. /// Returns:  
  126. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  127. //  
  128. +(NSData *)webSafeDecodeData:(NSData *)data;  
  129.   
  130. // webSafeEncodeBytes:length:padded:  
  131. //  
  132. /// WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES  
  133. /// then padding characters are added so the result length is a multiple of 4.  
  134. //  
  135. /// Returns:  
  136. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  137. //  
  138. +(NSData *)webSafeEncodeBytes:(const void *)bytes  
  139.                        length:(NSUInteger)length  
  140.                        padded:(BOOL)padded;  
  141.   
  142. // webSafeDecodeBytes:length:  
  143. //  
  144. /// WebSafe Base64 decodes the data pointed at by |bytes|.  
  145. //  
  146. /// Returns:  
  147. ///   A new autoreleased NSData with the encoded payload.  nil for any error.  
  148. //  
  149. +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length;  
  150.   
  151. // stringByWebSafeEncodingData:padded:  
  152. //  
  153. /// WebSafe Base64 encodes contents of the NSData object.  If |padded| is YES  
  154. /// then padding characters are added so the result length is a multiple of 4.  
  155. //  
  156. /// Returns:  
  157. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  158. //  
  159. +(NSString *)stringByWebSafeEncodingData:(NSData *)data  
  160.                                   padded:(BOOL)padded;  
  161.   
  162. // stringByWebSafeEncodingBytes:length:padded:  
  163. //  
  164. /// WebSafe Base64 encodes the data pointed at by |bytes|.  If |padded| is YES  
  165. /// then padding characters are added so the result length is a multiple of 4.  
  166. //  
  167. /// Returns:  
  168. ///   A new autoreleased NSString with the encoded payload.  nil for any error.  
  169. //  
  170. +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes  
  171.                                    length:(NSUInteger)length  
  172.                                    padded:(BOOL)padded;  
  173.   
  174. // webSafeDecodeString:  
  175. //  
  176. /// WebSafe Base64 decodes contents of the NSString.  
  177. //  
  178. /// Returns:  
  179. ///   A new autoreleased NSData with the decoded payload.  nil for any error.  
  180. //  
  181. +(NSData *)webSafeDecodeString:(NSString *)string;  
  182.   
  183. @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.   
  19. #import "GTMBase64.h"  
  20. #import "GTMDefines.h"  
  21.   
  22. static const char *kBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  23. static const char *kWebSafeBase64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";  
  24. static const char kBase64PaddingChar = '=';  
  25. static const char kBase64InvalidChar = 99;  
  26.   
  27. static const char kBase64DecodeChars[] = {  
  28.     // This array was generated by the following code:  
  29.     // #include <sys/time.h>  
  30.     // #include <stdlib.h>  
  31.     // #include <string.h>  
  32.     // main()  
  33.     // {  
  34.     //   static const char Base64[] =  
  35.     //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  36.     //   char *pos;  
  37.     //   int idx, i, j;  
  38.     //   printf("    ");  
  39.     //   for (i = 0; i < 255; i += 8) {  
  40.     //     for (j = i; j < i + 8; j++) {  
  41.     //       pos = strchr(Base64, j);  
  42.     //       if ((pos == NULL) || (j == 0))  
  43.     //         idx = 99;  
  44.     //       else  
  45.     //         idx = pos - Base64;  
  46.     //       if (idx == 99)  
  47.     //         printf(" %2d,     ", idx);  
  48.     //       else  
  49.     //         printf(" %2d/*%c*/,", idx, j);  
  50.     //     }  
  51.     //     printf("\n    ");  
  52.     //   }  
  53.     // }  
  54.     99,      99,      99,      99,      99,      99,      99,      99,  
  55.     99,      99,      99,      99,      99,      99,      99,      99,  
  56.     99,      99,      99,      99,      99,      99,      99,      99,  
  57.     99,      99,      99,      99,      99,      99,      99,      99,  
  58.     99,      99,      99,      99,      99,      99,      99,      99,  
  59.     99,      99,      99,      62/*+*/, 99,      99,      99,      63/*/ */,  
  60.     52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,  
  61.     60/*8*/, 61/*9*/, 99,      99,      99,      99,      99,      99,  
  62.     99,       0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/,  
  63.     7/*H*/,  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,  
  64.     15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,  
  65.     23/*X*/, 24/*Y*/, 25/*Z*/, 99,      99,      99,      99,      99,  
  66.     99,      26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,  
  67.     33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,  
  68.     41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,  
  69.     49/*x*/, 50/*y*/, 51/*z*/, 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.     99,      99,      99,      99,      99,      99,      99,      99,  
  84.     99,      99,      99,      99,      99,      99,      99,      99,  
  85.     99,      99,      99,      99,      99,      99,      99,      99  
  86. };  
  87.   
  88. static const char kWebSafeBase64DecodeChars[] = {  
  89.     // This array was generated by the following code:  
  90.     // #include <sys/time.h>  
  91.     // #include <stdlib.h>  
  92.     // #include <string.h>  
  93.     // main()  
  94.     // {  
  95.     //   static const char Base64[] =  
  96.     //     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";  
  97.     //   char *pos;  
  98.     //   int idx, i, j;  
  99.     //   printf("    ");  
  100.     //   for (i = 0; i < 255; i += 8) {  
  101.     //     for (j = i; j < i + 8; j++) {  
  102.     //       pos = strchr(Base64, j);  
  103.     //       if ((pos == NULL) || (j == 0))  
  104.     //         idx = 99;  
  105.     //       else  
  106.     //         idx = pos - Base64;  
  107.     //       if (idx == 99)  
  108.     //         printf(" %2d,     ", idx);  
  109.     //       else  
  110.     //         printf(" %2d/*%c*/,", idx, j);  
  111.     //     }  
  112.     //     printf("\n    ");  
  113.     //   }  
  114.     // }  
  115.     99,      99,      99,      99,      99,      99,      99,      99,  
  116.     99,      99,      99,      99,      99,      99,      99,      99,  
  117.     99,      99,      99,      99,      99,      99,      99,      99,  
  118.     99,      99,      99,      99,      99,      99,      99,      99,  
  119.     99,      99,      99,      99,      99,      99,      99,      99,  
  120.     99,      99,      99,      99,      99,      62/*-*/, 99,      99,  
  121.     52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,  
  122.     60/*8*/, 61/*9*/, 99,      99,      99,      99,      99,      99,  
  123.     99,       0/*A*/,  1/*B*/,  2/*C*/,  3/*D*/,  4/*E*/,  5/*F*/,  6/*G*/,  
  124.     7/*H*/,  8/*I*/,  9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,  
  125.     15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,  
  126.     23/*X*/, 24/*Y*/, 25/*Z*/, 99,      99,      99,      99,      63/*_*/,  
  127.     99,      26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,  
  128.     33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,  
  129.     41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,  
  130.     49/*x*/, 50/*y*/, 51/*z*/, 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.     99,      99,      99,      99,      99,      99,      99,      99,  
  144.     99,      99,      99,      99,      99,      99,      99,      99,  
  145.     99,      99,      99,      99,      99,      99,      99,      99,  
  146.     99,      99,      99,      99,      99,      99,      99,      99  
  147. };  
  148.   
  149.   
  150. // Tests a charact to see if it's a whitespace character.  
  151. //  
  152. // Returns:  
  153. //   YES if the character is a whitespace character.  
  154. //   NO if the character is not a whitespace character.  
  155. //  
  156. FOUNDATION_STATIC_INLINE BOOL IsSpace(unsigned char c) {  
  157.     // we use our own mapping here because we don't want anything w/ locale  
  158.     // support.  
  159.     static BOOL kSpaces[256] = {  
  160.         0, 0, 0, 0, 0, 0, 0, 0, 0, 1,  // 0-9  
  161.         1, 1, 1, 1, 0, 0, 0, 0, 0, 0,  // 10-19  
  162.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 20-29  
  163.         0, 0, 1, 0, 0, 0, 0, 0, 0, 0,  // 30-39  
  164.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 40-49  
  165.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 50-59  
  166.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 60-69  
  167.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 70-79  
  168.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 80-89  
  169.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 90-99  
  170.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 100-109  
  171.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 110-119  
  172.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 120-129  
  173.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 130-139  
  174.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 140-149  
  175.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 150-159  
  176.         1, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 160-169  
  177.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 170-179  
  178.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 180-189  
  179.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 190-199  
  180.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 200-209  
  181.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 210-219  
  182.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 220-229  
  183.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 230-239  
  184.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 240-249  
  185.         0, 0, 0, 0, 0, 1,              // 250-255  
  186.     };  
  187.     return kSpaces[c];  
  188. }  
  189.   
  190. // Calculate how long the data will be once it's base64 encoded.  
  191. //  
  192. // Returns:  
  193. //   The guessed encoded length for a source length  
  194. //  
  195. FOUNDATION_STATIC_INLINE NSUInteger CalcEncodedLength(NSUInteger srcLen,  
  196.                                                       BOOL padded) {  
  197.     NSUInteger intermediate_result = 8 * srcLen + 5;  
  198.     NSUInteger len = intermediate_result / 6;  
  199.     if (padded) {  
  200.         len = ((len + 3) / 4) * 4;  
  201.     }  
  202.     return len;  
  203. }  
  204.   
  205. // Tries to calculate how long the data will be once it's base64 decoded.  
  206. // Unlinke the above, this is always an upperbound, since the source data  
  207. // could have spaces and might end with the padding characters on them.  
  208. //  
  209. // Returns:  
  210. //   The guessed decoded length for a source length  
  211. //  
  212. FOUNDATION_STATIC_INLINE NSUInteger GuessDecodedLength(NSUInteger srcLen) {  
  213.     return (srcLen + 3) / 4 * 3;  
  214. }  
  215.   
  216.   
  217. @interface GTMBase64 (PrivateMethods)  
  218.   
  219. +(NSData *)baseEncode:(const void *)bytes  
  220.                length:(NSUInteger)length  
  221.               charset:(const char *)charset  
  222.                padded:(BOOL)padded;  
  223.   
  224. +(NSData *)baseDecode:(const void *)bytes  
  225.                length:(NSUInteger)length  
  226.               charset:(const char*)charset  
  227.        requirePadding:(BOOL)requirePadding;  
  228.   
  229. +(NSUInteger)baseEncode:(const char *)srcBytes  
  230.                  srcLen:(NSUInteger)srcLen  
  231.               destBytes:(char *)destBytes  
  232.                 destLen:(NSUInteger)destLen  
  233.                 charset:(const char *)charset  
  234.                  padded:(BOOL)padded;  
  235.   
  236. +(NSUInteger)baseDecode:(const char *)srcBytes  
  237.                  srcLen:(NSUInteger)srcLen  
  238.               destBytes:(char *)destBytes  
  239.                 destLen:(NSUInteger)destLen  
  240.                 charset:(const char *)charset  
  241.          requirePadding:(BOOL)requirePadding;  
  242.   
  243. @end  
  244.   
  245.   
  246. @implementation GTMBase64  
  247.   
  248. //  
  249. // Standard Base64 (RFC) handling  
  250. //  
  251.   
  252. +(NSData *)encodeData:(NSData *)data {  
  253.     return [self baseEncode:[data bytes]  
  254.                      length:[data length]  
  255.                     charset:kBase64EncodeChars  
  256.                      padded:YES];  
  257. }  
  258.   
  259. +(NSData *)decodeData:(NSData *)data {  
  260.     return [self baseDecode:[data bytes]  
  261.                      length:[data length]  
  262.                     charset:kBase64DecodeChars  
  263.              requirePadding:YES];  
  264. }  
  265.   
  266. +(NSData *)encodeBytes:(const void *)bytes length:(NSUInteger)length {  
  267.     return [self baseEncode:bytes  
  268.                      length:length  
  269.                     charset:kBase64EncodeChars  
  270.                      padded:YES];  
  271. }  
  272.   
  273. +(NSData *)decodeBytes:(const void *)bytes length:(NSUInteger)length {  
  274.     return [self baseDecode:bytes  
  275.                      length:length  
  276.                     charset:kBase64DecodeChars  
  277.              requirePadding:YES];  
  278. }  
  279.   
  280. +(NSString *)stringByEncodingData:(NSData *)data {  
  281.     NSString *result = nil;  
  282.     NSData *converted = [self baseEncode:[data bytes]  
  283.                                   length:[data length]  
  284.                                  charset:kBase64EncodeChars  
  285.                                   padded:YES];  
  286.     if (converted) {  
  287.         result = [[[NSString alloc] initWithData:converted  
  288.                                         encoding:NSASCIIStringEncoding] autorelease];  
  289.     }  
  290.     return result;  
  291. }  
  292.   
  293. +(NSString *)stringByEncodingBytes:(const void *)bytes length:(NSUInteger)length {  
  294.     NSString *result = nil;  
  295.     NSData *converted = [self baseEncode:bytes  
  296.                                   length:length  
  297.                                  charset:kBase64EncodeChars  
  298.                                   padded:YES];  
  299.     if (converted) {  
  300.         result = [[[NSString alloc] initWithData:converted  
  301.                                         encoding:NSASCIIStringEncoding] autorelease];  
  302.     }  
  303.     return result;  
  304. }  
  305.   
  306. +(NSData *)decodeString:(NSString *)string {  
  307.     NSData *result = nil;  
  308.     NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];  
  309.     if (data) {  
  310.         result = [self baseDecode:[data bytes]  
  311.                            length:[data length]  
  312.                           charset:kBase64DecodeChars  
  313.                    requirePadding:YES];  
  314.     }  
  315.     return result;  
  316. }  
  317.   
  318. //  
  319. // Modified Base64 encoding so the results can go onto urls.  
  320. //  
  321. // The changes are in the characters generated and also the result isn't  
  322. // padded to a multiple of 4.  
  323. // Must use the matching call to encode/decode, won't interop with the  
  324. // RFC versions.  
  325. //  
  326.   
  327. +(NSData *)webSafeEncodeData:(NSData *)data  
  328.                       padded:(BOOL)padded {  
  329.     return [self baseEncode:[data bytes]  
  330.                      length:[data length]  
  331.                     charset:kWebSafeBase64EncodeChars  
  332.                      padded:padded];  
  333. }  
  334.   
  335. +(NSData *)webSafeDecodeData:(NSData *)data {  
  336.     return [self baseDecode:[data bytes]  
  337.                      length:[data length]  
  338.                     charset:kWebSafeBase64DecodeChars  
  339.              requirePadding:NO];  
  340. }  
  341.   
  342. +(NSData *)webSafeEncodeBytes:(const void *)bytes  
  343.                        length:(NSUInteger)length  
  344.                        padded:(BOOL)padded {  
  345.     return [self baseEncode:bytes  
  346.                      length:length  
  347.                     charset:kWebSafeBase64EncodeChars  
  348.                      padded:padded];  
  349. }  
  350.   
  351. +(NSData *)webSafeDecodeBytes:(const void *)bytes length:(NSUInteger)length {  
  352.     return [self baseDecode:bytes  
  353.                      length:length  
  354.                     charset:kWebSafeBase64DecodeChars  
  355.              requirePadding:NO];  
  356. }  
  357.   
  358. +(NSString *)stringByWebSafeEncodingData:(NSData *)data  
  359.                                   padded:(BOOL)padded {  
  360.     NSString *result = nil;  
  361.     NSData *converted = [self baseEncode:[data bytes]  
  362.                                   length:[data length]  
  363.                                  charset:kWebSafeBase64EncodeChars  
  364.                                   padded:padded];  
  365.     if (converted) {  
  366.         result = [[[NSString alloc] initWithData:converted  
  367.                                         encoding:NSASCIIStringEncoding] autorelease];  
  368.     }  
  369.     return result;  
  370. }  
  371.   
  372. +(NSString *)stringByWebSafeEncodingBytes:(const void *)bytes  
  373.                                    length:(NSUInteger)length  
  374.                                    padded:(BOOL)padded {  
  375.     NSString *result = nil;  
  376.     NSData *converted = [self baseEncode:bytes  
  377.                                   length:length  
  378.                                  charset:kWebSafeBase64EncodeChars  
  379.                                   padded:padded];  
  380.     if (converted) {  
  381.         result = [[[NSString alloc] initWithData:converted  
  382.                                         encoding:NSASCIIStringEncoding] autorelease];  
  383.     }  
  384.     return result;  
  385. }  
  386.   
  387. +(NSData *)webSafeDecodeString:(NSString *)string {  
  388.     NSData *result = nil;  
  389.     NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding];  
  390.     if (data) {  
  391.         result = [self baseDecode:[data bytes]  
  392.                            length:[data length]  
  393.                           charset:kWebSafeBase64DecodeChars  
  394.                    requirePadding:NO];  
  395.     }  
  396.     return result;  
  397. }  
  398.   
  399. @end  
  400.   
  401. @implementation GTMBase64 (PrivateMethods)  
  402.   
  403. //  
  404. // baseEncode:length:charset:padded:  
  405. //  
  406. // Does the common lifting of creating the dest NSData.  it creates & sizes the  
  407. // data for the results.  |charset| is the characters to use for the encoding  
  408. // of the data.  |padding| controls if the encoded data should be padded to a  
  409. // multiple of 4.  
  410. //  
  411. // Returns:  
  412. //   an autorelease NSData with the encoded data, nil if any error.  
  413. //  
  414. +(NSData *)baseEncode:(const void *)bytes  
  415.                length:(NSUInteger)length  
  416.               charset:(const char *)charset  
  417.                padded:(BOOL)padded {  
  418.     // how big could it be?  
  419.     NSUInteger maxLength = CalcEncodedLength(length, padded);  
  420.     // make space  
  421.     NSMutableData *result = [NSMutableData data];  
  422.     [result setLength:maxLength];  
  423.     // do it  
  424.     NSUInteger finalLength = [self baseEncode:bytes  
  425.                                        srcLen:length  
  426.                                     destBytes:[result mutableBytes]  
  427.                                       destLen:[result length]  
  428.                                       charset:charset  
  429.                                        padded:padded];  
  430.     if (finalLength) {  
  431.         _GTMDevAssert(finalLength == maxLength, @"how did we calc the length wrong?");  
  432.     } else {  
  433.         // shouldn't happen, this means we ran out of space  
  434.         result = nil;  
  435.     }  
  436.     return result;  
  437. }  
  438.   
  439. //  
  440. // baseDecode:length:charset:requirePadding:  
  441. //  
  442. // Does the common lifting of creating the dest NSData.  it creates & sizes the  
  443. // data for the results.  |charset| is the characters to use for the decoding  
  444. // of the data.  
  445. //  
  446. // Returns:  
  447. //   an autorelease NSData with the decoded data, nil if any error.  
  448. //  
  449. //  
  450. +(NSData *)baseDecode:(const void *)bytes  
  451.                length:(NSUInteger)length  
  452.               charset:(const char *)charset  
  453.        requirePadding:(BOOL)requirePadding {  
  454.     // could try to calculate what it will end up as  
  455.     NSUInteger maxLength = GuessDecodedLength(length);  
  456.     // make space  
  457.     NSMutableData *result = [NSMutableData data];  
  458.     [result setLength:maxLength];  
  459.     // do it  
  460.     NSUInteger finalLength = [self baseDecode:bytes  
  461.                                        srcLen:length  
  462.                                     destBytes:[result mutableBytes]  
  463.                                       destLen:[result length]  
  464.                                       charset:charset  
  465.                                requirePadding:requirePadding];  
  466.     if (finalLength) {  
  467.         if (finalLength != maxLength) {  
  468.             // resize down to how big it was  
  469.             [result setLength:finalLength];  
  470.         }  
  471.     } else {  
  472.         // either an error in the args, or we ran out of space  
  473.         result = nil;  
  474.     }  
  475.     return result;  
  476. }  
  477.   
  478. //  
  479. // baseEncode:srcLen:destBytes:destLen:charset:padded:  
  480. //  
  481. // Encodes the buffer into the larger.  returns the length of the encoded  
  482. // data, or zero for an error.  
  483. // |charset| is the characters to use for the encoding  
  484. // |padded| tells if the result should be padded to a multiple of 4.  
  485. //  
  486. // Returns:  
  487. //   the length of the encoded data.  zero if any error.  
  488. //  
  489. +(NSUInteger)baseEncode:(const char *)srcBytes  
  490.                  srcLen:(NSUInteger)srcLen  
  491.               destBytes:(char *)destBytes  
  492.                 destLen:(NSUInteger)destLen  
  493.                 charset:(const char *)charset  
  494.                  padded:(BOOL)padded {  
  495.     if (!srcLen || !destLen || !srcBytes || !destBytes) {  
  496.         return 0;  
  497.     }  
  498.       
  499.     char *curDest = destBytes;  
  500.     const unsigned char *curSrc = (const unsigned char *)(srcBytes);  
  501.       
  502.     // Three bytes of data encodes to four characters of cyphertext.  
  503.     // So we can pump through three-byte chunks atomically.  
  504.     while (srcLen > 2) {  
  505.         // space?  
  506.         _GTMDevAssert(destLen >= 4, @"our calc for encoded length was wrong");  
  507.         curDest[0] = charset[curSrc[0] >> 2];  
  508.         curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];  
  509.         curDest[2] = charset[((curSrc[1] & 0x0f) << 2) + (curSrc[2] >> 6)];  
  510.         curDest[3] = charset[curSrc[2] & 0x3f];  
  511.           
  512.         curDest += 4;  
  513.         curSrc += 3;  
  514.         srcLen -= 3;  
  515.         destLen -= 4;  
  516.     }  
  517.       
  518.     // now deal with the tail (<=2 bytes)  
  519.     switch (srcLen) {  
  520.         case 0:  
  521.             // Nothing left; nothing more to do.  
  522.             break;  
  523.         case 1:  
  524.             // One byte left: this encodes to two characters, and (optionally)  
  525.             // two pad characters to round out the four-character cypherblock.  
  526.             _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");  
  527.             curDest[0] = charset[curSrc[0] >> 2];  
  528.             curDest[1] = charset[(curSrc[0] & 0x03) << 4];  
  529.             curDest += 2;  
  530.             destLen -= 2;  
  531.             if (padded) {  
  532.                 _GTMDevAssert(destLen >= 2, @"our calc for encoded length was wrong");  
  533.                 curDest[0] = kBase64PaddingChar;  
  534.                 curDest[1] = kBase64PaddingChar;  
  535.                 curDest += 2;  
  536.                 destLen -= 2;  
  537.             }  
  538.             break;  
  539.         case 2:  
  540.             // Two bytes left: this encodes to three characters, and (optionally)  
  541.             // one pad character to round out the four-character cypherblock.  
  542.             _GTMDevAssert(destLen >= 3, @"our calc for encoded length was wrong");  
  543.             curDest[0] = charset[curSrc[0] >> 2];  
  544.             curDest[1] = charset[((curSrc[0] & 0x03) << 4) + (curSrc[1] >> 4)];  
  545.             curDest[2] = charset[(curSrc[1] & 0x0f) << 2];  
  546.             curDest += 3;  
  547.             destLen -= 3;  
  548.             if (padded) {  
  549.                 _GTMDevAssert(destLen >= 1, @"our calc for encoded length was wrong");  
  550.                 curDest[0] = kBase64PaddingChar;  
  551.                 curDest += 1;  
  552.                 destLen -= 1;  
  553.             }  
  554.             break;  
  555.     }  
  556.     // return the length  
  557.     return (curDest - destBytes);  
  558. }  
  559.   
  560. //  
  561. // baseDecode:srcLen:destBytes:destLen:charset:requirePadding:  
  562. //  
  563. // Decodes the buffer into the larger.  returns the length of the decoded  
  564. // data, or zero for an error.  
  565. // |charset| is the character decoding buffer to use  
  566. //  
  567. // Returns:  
  568. //   the length of the encoded data.  zero if any error.  
  569. //  
  570. +(NSUInteger)baseDecode:(const char *)srcBytes  
  571.                  srcLen:(NSUInteger)srcLen  
  572.               destBytes:(char *)destBytes  
  573.                 destLen:(NSUInteger)destLen  
  574.                 charset:(const char *)charset  
  575.          requirePadding:(BOOL)requirePadding {  
  576.     if (!srcLen || !destLen || !srcBytes || !destBytes) {  
  577.         return 0;  
  578.     }  
  579.       
  580.     int decode;  
  581.     NSUInteger destIndex = 0;  
  582.     int state = 0;  
  583.     char ch = 0;  
  584.     while (srcLen-- && (ch = *srcBytes++) != 0)  {  
  585.         if (IsSpace(ch))  // Skip whitespace  
  586.             continue;  
  587.           
  588.         if (ch == kBase64PaddingChar)  
  589.             break;  
  590.           
  591.         decode = charset[(unsigned int)ch];  
  592.         if (decode == kBase64InvalidChar)  
  593.             return 0;  
  594.           
  595.         // Four cyphertext characters decode to three bytes.  
  596.         // Therefore we can be in one of four states.  
  597.         switch (state) {  
  598.             case 0:  
  599.                 // We're at the beginning of a four-character cyphertext block.  
  600.                 // This sets the high six bits of the first byte of the  
  601.                 // plaintext block.  
  602.                 _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");  
  603.                 destBytes[destIndex] = decode << 2;  
  604.                 state = 1;  
  605.                 break;  
  606.             case 1:  
  607.                 // We're one character into a four-character cyphertext block.  
  608.                 // This sets the low two bits of the first plaintext byte,  
  609.                 // and the high four bits of the second plaintext byte.  
  610.                 _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");  
  611.                 destBytes[destIndex] |= decode >> 4;  
  612.                 destBytes[destIndex+1] = (decode & 0x0f) << 4;  
  613.                 destIndex++;  
  614.                 state = 2;  
  615.                 break;  
  616.             case 2:  
  617.                 // We're two characters into a four-character cyphertext block.  
  618.                 // This sets the low four bits of the second plaintext  
  619.                 // byte, and the high two bits of the third plaintext byte.  
  620.                 // However, if this is the end of data, and those two  
  621.                 // bits are zero, it could be that those two bits are  
  622.                 // leftovers from the encoding of data that had a length  
  623.                 // of two mod three.  
  624.                 _GTMDevAssert((destIndex+1) < destLen, @"our calc for decoded length was wrong");  
  625.                 destBytes[destIndex] |= decode >> 2;  
  626.                 destBytes[destIndex+1] = (decode & 0x03) << 6;  
  627.                 destIndex++;  
  628.                 state = 3;  
  629.                 break;  
  630.             case 3:  
  631.                 // We're at the last character of a four-character cyphertext block.  
  632.                 // This sets the low six bits of the third plaintext byte.  
  633.                 _GTMDevAssert(destIndex < destLen, @"our calc for decoded length was wrong");  
  634.                 destBytes[destIndex] |= decode;  
  635.                 destIndex++;  
  636.                 state = 0;  
  637.                 break;  
  638.         }  
  639.     }  
  640.       
  641.     // We are done decoding Base-64 chars.  Let's see if we ended  
  642.     //      on a byte boundary, and/or with erroneous trailing characters.  
  643.     if (ch == kBase64PaddingChar) {               // We got a pad char  
  644.         if ((state == 0) || (state == 1)) {  
  645.             return 0;  // Invalid '=' in first or second position  
  646.         }  
  647.         if (srcLen == 0) {  
  648.             if (state == 2) { // We run out of input but we still need another '='  
  649.                 return 0;  
  650.             }  
  651.             // Otherwise, we are in state 3 and only need this '='  
  652.         } else {  
  653.             if (state == 2) {  // need another '='  
  654.                 while ((ch = *srcBytes++) && (srcLen-- > 0)) {  
  655.                     if (!IsSpace(ch))  
  656.                         break;  
  657.                 }  
  658.                 if (ch != kBase64PaddingChar) {  
  659.                     return 0;  
  660.                 }  
  661.             }  
  662.             // state = 1 or 2, check if all remain padding is space  
  663.             while ((ch = *srcBytes++) && (srcLen-- > 0)) {  
  664.                 if (!IsSpace(ch)) {  
  665.                     return 0;  
  666.                 }  
  667.             }  
  668.         }  
  669.     } else {  
  670.         // We ended by seeing the end of the string.  
  671.           
  672.         if (requirePadding) {  
  673.             // If we require padding, then anything but state 0 is an error.  
  674.             if (state != 0) {  
  675.                 return 0;  
  676.             }  
  677.         } else {  
  678.             // Make sure we have no partial bytes lying around.  Note that we do not  
  679.             // require trailing '=', so states 2 and 3 are okay too.  
  680.             if (state == 1) {  
  681.                 return 0;  
  682.             }  
  683.         }  
  684.     }  
  685.       
  686.     // If then next piece of output was valid and got written to it means we got a  
  687.     // very carefully crafted input that appeared valid but contains some trailing  
  688.     // bits past the real length, so just toss the thing.  
  689.     if ((destIndex < destLen) &&  
  690.         (destBytes[destIndex] != 0)) {  
  691.         return 0;  
  692.     }  
  693.       
  694.     return destIndex;  
  695. }  
  696.   
  697. @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. // ============================================================================  
  20.   
  21. #include <AvailabilityMacros.h>  
  22.   
  23. // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs  
  24. #ifndef MAC_OS_X_VERSION_10_5  
  25. #define MAC_OS_X_VERSION_10_5 1050  
  26. #endif  
  27. #ifndef MAC_OS_X_VERSION_10_6  
  28. #define MAC_OS_X_VERSION_10_6 1060  
  29. #endif  
  30.   
  31. // ----------------------------------------------------------------------------  
  32. // CPP symbols that can be overridden in a prefix to control how the toolbox  
  33. // is compiled.  
  34. // ----------------------------------------------------------------------------  
  35.   
  36.   
  37. // GTMHTTPFetcher will support logging by default but only hook its input  
  38. // stream support for logging when requested.  You can control the inclusion of  
  39. // the code by providing your own definitions for these w/in a prefix header.  
  40. //  
  41. #ifndef GTM_HTTPFETCHER_ENABLE_LOGGING  
  42. #define GTM_HTTPFETCHER_ENABLE_LOGGING 1  
  43. #endif // GTM_HTTPFETCHER_ENABLE_LOGGING  
  44. #ifndef GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING  
  45. #define GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING 0  
  46. #endif // GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING  
  47.   
  48. // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and  
  49. // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens  
  50. // when a validation fails. If you implement your own validators, you may want  
  51. // to control their internals using the same macros for consistency.  
  52. #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT  
  53. #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0  
  54. #endif  
  55.   
  56. // Give ourselves a consistent way to do inlines.  Apple's macros even use  
  57. // a few different actual definitions, so we're based off of the foundation  
  58. // one.  
  59. #if !defined(GTM_INLINE)  
  60. #if defined (__GNUC__) && (__GNUC__ == 4)  
  61. #define GTM_INLINE static __inline__ __attribute__((always_inline))  
  62. #else  
  63. #define GTM_INLINE static __inline__  
  64. #endif  
  65. #endif  
  66.   
  67. // Give ourselves a consistent way of doing externs that links up nicely  
  68. // when mixing objc and objc++  
  69. #if !defined (GTM_EXTERN)  
  70. #if defined __cplusplus  
  71. #define GTM_EXTERN extern "C"  
  72. #else  
  73. #define GTM_EXTERN extern  
  74. #endif  
  75. #endif  
  76.   
  77. // Give ourselves a consistent way of exporting things if we have visibility  
  78. // set to hidden.  
  79. #if !defined (GTM_EXPORT)  
  80. #define GTM_EXPORT __attribute__((visibility("default")))  
  81. #endif  
  82.   
  83. // _GTMDevLog & _GTMDevAssert  
  84. //  
  85. // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for  
  86. // developer level errors.  This implementation simply macros to NSLog/NSAssert.  
  87. // It is not intended to be a general logging/reporting system.  
  88. //  
  89. // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert  
  90. // for a little more background on the usage of these macros.  
  91. //  
  92. //    _GTMDevLog           log some error/problem in debug builds  
  93. //    _GTMDevAssert        assert if conditon isn't met w/in a method/function  
  94. //                           in all builds.  
  95. //  
  96. // To replace this system, just provide different macro definitions in your  
  97. // prefix header.  Remember, any implementation you provide *must* be thread  
  98. // safe since this could be called by anything in what ever situtation it has  
  99. // been placed in.  
  100. //  
  101.   
  102. // We only define the simple macros if nothing else has defined this.  
  103. #ifndef _GTMDevLog  
  104.   
  105. #ifdef DEBUG  
  106. #define _GTMDevLog(...) NSLog(__VA_ARGS__)  
  107. #else  
  108. #define _GTMDevLog(...) do { } while (0)  
  109. #endif  
  110.   
  111. #endif // _GTMDevLog  
  112.   
  113. // Declared here so that it can easily be used for logging tracking if  
  114. // necessary. See GTMUnitTestDevLog.h for details.  
  115. @class NSString;  
  116. GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);  
  117.   
  118. #ifndef _GTMDevAssert  
  119. // we directly invoke the NSAssert handler so we can pass on the varargs  
  120. // (NSAssert doesn't have a macro we can use that takes varargs)  
  121. #if !defined(NS_BLOCK_ASSERTIONS)  
  122. #define _GTMDevAssert(condition, ...)                                       \  
  123. do {                                                                      \  
  124. if (!(condition)) {                                                     \  
  125. [[NSAssertionHandler currentHandler]                                  \  
  126. handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \  
  127. file:[NSString stringWithUTF8String:__FILE__]  \  
  128. lineNumber:__LINE__                                  \  
  129. description:__VA_ARGS__];                             \  
  130. }                                                                       \  
  131. while(0)  
  132. #else // !defined(NS_BLOCK_ASSERTIONS)  
  133. #define _GTMDevAssert(condition, ...) do { } while (0)  
  134. #endif // !defined(NS_BLOCK_ASSERTIONS)  
  135.   
  136. #endif // _GTMDevAssert  
  137.   
  138. // _GTMCompileAssert  
  139. // _GTMCompileAssert is an assert that is meant to fire at compile time if you  
  140. // want to check things at compile instead of runtime. For example if you  
  141. // want to check that a wchar is 4 bytes instead of 2 you would use  
  142. // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)  
  143. // Note that the second "arg" is not in quotes, and must be a valid processor  
  144. // symbol in it's own right (no spaces, punctuation etc).  
  145.   
  146. // Wrapping this in an #ifndef allows external groups to define their own  
  147. // compile time assert scheme.  
  148. #ifndef _GTMCompileAssert  
  149. // We got this technique from here:  
  150. // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html  
  151.   
  152. #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg  
  153. #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)  
  154. #define _GTMCompileAssert(test, msg) \  
  155. typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]  
  156. #endif // _GTMCompileAssert  
  157.   
  158. // Macro to allow fast enumeration when building for 10.5 or later, and  
  159. // reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration  
  160. // does keys, so pick the right thing, nothing is done on the FastEnumeration  
  161. // side to be sure you're getting what you wanted.  
  162. #ifndef GTM_FOREACH_OBJECT  
  163. #if defined(TARGET_OS_IPHONE) || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)  
  164. #define GTM_FOREACH_OBJECT(element, collection) \  
  165. for (element in collection)  
  166. #define GTM_FOREACH_KEY(element, collection) \  
  167. for (element in collection)  
  168. #else  
  169. #define GTM_FOREACH_OBJECT(element, collection) \  
  170. for (NSEnumerator * _ ## element ## _enum = [collection objectEnumerator]; \  
  171. (element = [_ ## element ## _enum nextObject]) != nil; )  
  172. #define GTM_FOREACH_KEY(element, collection) \  
  173. for (NSEnumerator * _ ## element ## _enum = [collection keyEnumerator]; \  
  174. (element = [_ ## element ## _enum nextObject]) != nil; )  
  175. #endif  
  176. #endif  
  177.   
  178. // ============================================================================  
  179.   
  180. // ----------------------------------------------------------------------------  
  181. // CPP symbols defined based on the project settings so the GTM code has  
  182. // simple things to test against w/o scattering the knowledge of project  
  183. // setting through all the code.  
  184. // ----------------------------------------------------------------------------  
  185.   
  186. // Provide a single constant CPP symbol that all of GTM uses for ifdefing  
  187. // iPhone code.  
  188. #include <TargetConditionals.h>  
  189. #if TARGET_OS_IPHONE // iPhone SDK  
  190. // For iPhone specific stuff  
  191. #define GTM_IPHONE_SDK 1  
  192. #if TARGET_IPHONE_SIMULATOR  
  193. #define GTM_IPHONE_SIMULATOR 1  
  194. #else  
  195. #define GTM_IPHONE_DEVICE 1  
  196. #endif  // TARGET_IPHONE_SIMULATOR  
  197. #else  
  198. // For MacOS specific stuff  
  199. #define GTM_MACOS_SDK 1  
  200. #endif  
  201.   
  202. // Provide a symbol to include/exclude extra code for GC support.  (This mainly  
  203. // just controls the inclusion of finalize methods).  
  204. #ifndef GTM_SUPPORT_GC  
  205. #if GTM_IPHONE_SDK  
  206. // iPhone never needs GC  
  207. #define GTM_SUPPORT_GC 0  
  208. #else  
  209. // We can't find a symbol to tell if GC is supported/required, so best we  
  210. // do on Mac targets is include it if we're on 10.5 or later.  
  211. #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4  
  212. #define GTM_SUPPORT_GC 0  
  213. #else  
  214. #define GTM_SUPPORT_GC 1  
  215. #endif  
  216. #endif  
  217. #endif  
  218.   
  219. // To simplify support for 64bit (and Leopard in general), we provide the type  
  220. // defines for non Leopard SDKs  
  221. #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4  
  222. // NSInteger/NSUInteger and Max/Mins  
  223. #ifndef NSINTEGER_DEFINED  
  224. #if __LP64__ || NS_BUILD_32_LIKE_64  
  225. typedef long NSInteger;  
  226. typedef unsigned long NSUInteger;  
  227. #else  
  228. typedef int NSInteger;  
  229. typedef unsigned int NSUInteger;  
  230. #endif  
  231. #define NSIntegerMax    LONG_MAX  
  232. #define NSIntegerMin    LONG_MIN  
  233. #define NSUIntegerMax   ULONG_MAX  
  234. #define NSINTEGER_DEFINED 1  
  235. #endif  // NSINTEGER_DEFINED  
  236. // CGFloat  
  237. #ifndef CGFLOAT_DEFINED  
  238. #if defined(__LP64__) && __LP64__  
  239. // This really is an untested path (64bit on Tiger?)  
  240. typedef double CGFloat;  
  241. #define CGFLOAT_MIN DBL_MIN  
  242. #define CGFLOAT_MAX DBL_MAX  
  243. #define CGFLOAT_IS_DOUBLE 1  
  244. #else /* !defined(__LP64__) || !__LP64__ */  
  245. typedef float CGFloat;  
  246. #define CGFLOAT_MIN FLT_MIN  
  247. #define CGFLOAT_MAX FLT_MAX  
  248. #define CGFLOAT_IS_DOUBLE 0  
  249. #endif /* !defined(__LP64__) || !__LP64__ */  
  250. #define CGFLOAT_DEFINED 1  
  251. #endif // CGFLOAT_DEFINED  
  252. #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 =中华人民共和国万岁!!

2016-06-16 15:15:57 scotty_ke 阅读数 1741
  • iOS逆向开发案例

    本套课程相信能够帮助到想学习逆向的你,为你节约大量的时间,将时间充分运用到实践的过程中,并非在逆向的“门前”爬坑。在这个系列里,我们从密码学入手,了解常见加密算法,通过数字签名等技术学习iOS应用签名。剖析原理,通过重签名技术绕过系统检测开启逆向之旅。

    7585 人正在学习 去看看 李文瀚

        在iOS开发中,我们经常会用到网络请求,在网络请求的过程中,我们经常需要想服务器发送参数,其中就包括帐号密码一类,在发送这些参数的时候,直接发送明文是不安全的,因此我们需要对明文进行加密。今天介绍第一种加密方法:base64加密

     base64加密可以对任意文件进行加密,但是这种加密过程是可逆的,可以被反解密。base64加密的原理是将8个bit为一个字节的数据转换成6个bit为一个单位来处理,这样就导致数据增大了(8-6)/6 = 1/3.

    NSString *str = @"I love china";

    

    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];

    

    NSData *base64Data = [data base64EncodedDataWithOptions:0];

    

    NSString *base64Str = [data base64EncodedStringWithOptions:0];


对文件的加密解密过程如下:

    NSString *path = @"文件路径";

    

    NSData *data = [NSData dataWithContentsOfFile:path];

    

    NSData *base64Data = [data base64EncodedDataWithOptions:0];

    

    [base64Data writeToFile:@"要写入的文件路径" atomically:YES];

          

解密

    NSData *endata = [[NSData alloc]initWithBase64EncodedData:base64Data options:0];

  

    [endata writeToFile:@"解密出来的文件存放的位置" atomically:YES];


 最后将解密出来的data转换成你需要的类型就可以了





iOS MD5 和 Base64加密

阅读数 3314

没有更多推荐了,返回首页