Base64.m
author Jens Alfke <jens@mooseyard.com>
Wed Sep 02 08:41:25 2009 -0700 (2009-09-02)
changeset 35 5cab3034d3a1
parent 11 e5976864dfe9
permissions -rw-r--r--
10.6 compatibility: Fix some new compiler warnings, and work around apparent regressions in NSTask and -stringByStandardizingPath.
     1 //
     2 //  Base64.m
     3 //  MYUtilities
     4 //
     5 //  Created by Jens Alfke on 1/27/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 //  Portions adapted from SSCrypto.m by Ed Silva;
     9 //  Copyright (c) 2003-2006 Septicus Software. All rights reserved.
    10 //  Portions taken from uncopyrighted code posted by Dave Dribin.
    11 //
    12 
    13 #import "Base64.h"
    14 
    15 //NOTE: Using this requires linking against /usr/lib/libcrypto.dylib.
    16 #import <openssl/bio.h>
    17 #import <openssl/evp.h>
    18 
    19 
    20 @implementation NSData (MYBase64)
    21 
    22 
    23 /**
    24  * Encodes the current data in base64, and creates and returns an NSString from the result.
    25  * This is the same as piping data through "... | openssl enc -base64" on the command line.
    26  *
    27  * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
    28  * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
    29  **/
    30 - (NSString *)my_base64String
    31 {
    32     return [self my_base64StringWithNewlines: YES];
    33 }
    34 
    35 /**
    36  * Encodes the current data in base64, and creates and returns an NSString from the result.
    37  * This is the same as piping data through "... | openssl enc -base64" on the command line.
    38  *
    39  * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
    40  * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
    41  **/
    42 - (NSString *)my_base64StringWithNewlines:(BOOL)encodeWithNewlines
    43 {
    44     // Create a memory buffer which will contain the Base64 encoded string
    45     BIO * mem = BIO_new(BIO_s_mem());
    46     
    47     // Push on a Base64 filter so that writing to the buffer encodes the data
    48     BIO * b64 = BIO_new(BIO_f_base64());
    49     if (!encodeWithNewlines)
    50         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    51     mem = BIO_push(b64, mem);
    52     
    53     // Encode all the data
    54     BIO_write(mem, [self bytes], [self length]);
    55     BIO_flush(mem);
    56     
    57     // Create a new string from the data in the memory buffer
    58     char * base64Pointer;
    59     long base64Length = BIO_get_mem_data(mem, &base64Pointer);
    60     NSString * base64String = [NSString stringWithCString:base64Pointer length:base64Length];
    61     
    62     // Clean up and go home
    63     BIO_free_all(mem);
    64     return base64String;
    65 }
    66 
    67 - (NSData *)my_decodeBase64
    68 {
    69     return [self my_decodeBase64WithNewLines:YES];
    70 }
    71 
    72 - (NSData *)my_decodeBase64WithNewLines:(BOOL)encodedWithNewlines
    73 {
    74     // Create a memory buffer containing Base64 encoded string data
    75     BIO * mem = BIO_new_mem_buf((void *) [self bytes], [self length]);
    76     
    77     // Push a Base64 filter so that reading from the buffer decodes it
    78     BIO * b64 = BIO_new(BIO_f_base64());
    79     if (!encodedWithNewlines)
    80         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    81     mem = BIO_push(b64, mem);
    82     
    83     // Decode into an NSMutableData
    84     NSMutableData * data = [NSMutableData data];
    85     char inbuf[512];
    86     int inlen;
    87     while ((inlen = BIO_read(mem, inbuf, sizeof(inbuf))) > 0)
    88         [data appendBytes: inbuf length: inlen];
    89     
    90     // Clean up and go home
    91     BIO_free_all(mem);
    92     return data;
    93 }
    94 
    95 
    96 - (NSString *)my_hexString
    97 {
    98     //  Adapted from SSCrypto.m by Ed Silva:
    99     //  Copyright (c) 2003-2006 Septicus Software. All rights reserved.
   100     const UInt8 *bytes = self.bytes;
   101     NSUInteger length = self.length;
   102     char out[2*length+1];
   103     char *dst = &out[0];
   104     for( NSUInteger i=0; i<length; i+=1 )
   105         dst += sprintf(dst,"%02X",*(bytes++));
   106     return [[[NSString alloc] initWithBytes: out length: 2*length encoding: NSASCIIStringEncoding]
   107             autorelease];
   108 }
   109 
   110 - (NSString *)my_hexDump
   111 {
   112     //  Adapted from SSCrypto.m by Ed Silva:
   113     //  Copyright (c) 2003-2006 Septicus Software. All rights reserved.
   114     NSMutableString *ret=[NSMutableString stringWithCapacity:[self length]*2];
   115     /* dumps size bytes of *data to string. Looks like:
   116      * [0000] 75 6E 6B 6E 6F 77 6E 20
   117      *                  30 FF 00 00 00 00 39 00 unknown 0.....9.
   118      * (in a single line of course)
   119      */
   120     unsigned int size= [self length];
   121     const unsigned char *p = [self bytes];
   122     unsigned char c;
   123     unsigned int n;
   124     char bytestr[4] = {0};
   125     char addrstr[10] = {0};
   126     char hexstr[ 16*3 + 5] = {0};
   127     char charstr[16*1 + 5] = {0};
   128     for(n=1;n<=size;n++) {
   129         if (n%16 == 1) {
   130             /* store address for this line */
   131             snprintf(addrstr, sizeof(addrstr), "%.4x",
   132                      ((unsigned int)p-(unsigned int)self) );
   133         }
   134         
   135         c = *p;
   136         if (isalnum(c) == 0) {
   137             c = '.';
   138         }
   139         
   140         /* store hex str (for left side) */
   141         snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
   142         strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
   143         
   144         /* store char str (for right side) */
   145         snprintf(bytestr, sizeof(bytestr), "%c", c);
   146         strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
   147         
   148         if(n%16 == 0) {
   149             /* line completed */
   150             //printf("[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
   151             [ret appendString:[NSString stringWithFormat:@"[%4.4s]   %-50.50s  %s\n",
   152                                addrstr, hexstr, charstr]];
   153             hexstr[0] = 0;
   154             charstr[0] = 0;
   155         } else if(n%8 == 0) {
   156             /* half line: add whitespaces */
   157             strncat(hexstr, "  ", sizeof(hexstr)-strlen(hexstr)-1);
   158             strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
   159         }
   160         p++; /* next byte */
   161     }
   162     
   163     if (strlen(hexstr) > 0) {
   164         /* print rest of buffer if not empty */
   165         //printf("[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
   166         [ret appendString:[NSString stringWithFormat:@"[%4.4s]   %-50.50s  %s\n",
   167                            addrstr, hexstr, charstr]];
   168     }
   169     return ret;
   170 }
   171 
   172 @end
   173 
   174 
   175 /*
   176  Copyright (c) 2008, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   177  
   178  Redistribution and use in source and binary forms, with or without modification, are permitted
   179  provided that the following conditions are met:
   180  
   181  * Redistributions of source code must retain the above copyright notice, this list of conditions
   182  and the following disclaimer.
   183  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   184  and the following disclaimer in the documentation and/or other materials provided with the
   185  distribution.
   186  
   187  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   188  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   189  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   190  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   191  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   192   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   193  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   194  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   195  */