Base64.m
author Jens Alfke <jens@mooseyard.com>
Fri Apr 18 09:25:10 2008 -0700 (2008-04-18)
changeset 6 2d492d8c2053
parent 0 d84d25d6cdbb
child 11 e5976864dfe9
permissions -rw-r--r--
Added -reopenWith:.
     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 //  Adapted from SSCrypto.m by Ed Silva;
     9 //  Copyright (c) 2003-2006 Septicus Software. All rights reserved.
    10 //
    11 
    12 #import "Base64.h"
    13 
    14 //NOTE: Using this requires linking against /usr/lib/libcrypto.dylib.
    15 #import <openssl/bio.h>
    16 #import <openssl/evp.h>
    17 
    18 
    19 @implementation NSData (MYBase64)
    20 
    21 
    22 /**
    23  * Encodes the current data in base64, and creates and returns an NSString from the result.
    24  * This is the same as piping data through "... | openssl enc -base64" on the command line.
    25  *
    26  * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
    27  * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
    28  **/
    29 - (NSString *)my_base64String
    30 {
    31     return [self my_base64StringWithNewlines: YES];
    32 }
    33 
    34 /**
    35  * Encodes the current data in base64, and creates and returns an NSString from the result.
    36  * This is the same as piping data through "... | openssl enc -base64" on the command line.
    37  *
    38  * Code courtesy of DaveDribin (http://www.dribin.org/dave/)
    39  * Taken from http://www.cocoadev.com/index.pl?BaseSixtyFour
    40  **/
    41 - (NSString *)my_base64StringWithNewlines:(BOOL)encodeWithNewlines
    42 {
    43     // Create a memory buffer which will contain the Base64 encoded string
    44     BIO * mem = BIO_new(BIO_s_mem());
    45     
    46     // Push on a Base64 filter so that writing to the buffer encodes the data
    47     BIO * b64 = BIO_new(BIO_f_base64());
    48     if (!encodeWithNewlines)
    49         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    50     mem = BIO_push(b64, mem);
    51     
    52     // Encode all the data
    53     BIO_write(mem, [self bytes], [self length]);
    54     BIO_flush(mem);
    55     
    56     // Create a new string from the data in the memory buffer
    57     char * base64Pointer;
    58     long base64Length = BIO_get_mem_data(mem, &base64Pointer);
    59     NSString * base64String = [NSString stringWithCString:base64Pointer length:base64Length];
    60     
    61     // Clean up and go home
    62     BIO_free_all(mem);
    63     return base64String;
    64 }
    65 
    66 - (NSData *)my_decodeBase64
    67 {
    68     return [self my_decodeBase64WithNewLines:YES];
    69 }
    70 
    71 - (NSData *)my_decodeBase64WithNewLines:(BOOL)encodedWithNewlines
    72 {
    73     // Create a memory buffer containing Base64 encoded string data
    74     BIO * mem = BIO_new_mem_buf((void *) [self bytes], [self length]);
    75     
    76     // Push a Base64 filter so that reading from the buffer decodes it
    77     BIO * b64 = BIO_new(BIO_f_base64());
    78     if (!encodedWithNewlines)
    79         BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    80     mem = BIO_push(b64, mem);
    81     
    82     // Decode into an NSMutableData
    83     NSMutableData * data = [NSMutableData data];
    84     char inbuf[512];
    85     int inlen;
    86     while ((inlen = BIO_read(mem, inbuf, sizeof(inbuf))) > 0)
    87         [data appendBytes: inbuf length: inlen];
    88     
    89     // Clean up and go home
    90     BIO_free_all(mem);
    91     return data;
    92 }
    93 
    94 
    95 - (NSString *)my_hexString
    96 {
    97     const UInt8 *bytes = self.bytes;
    98     NSUInteger length = self.length;
    99     char out[2*length+1];
   100     char *dst = &out[0];
   101     for( int i=0; i<length; i+=1 )
   102         dst += sprintf(dst,"%02X",*(bytes++));
   103     return [[[NSString alloc] initWithBytes: out length: 2*length encoding: NSASCIIStringEncoding]
   104             autorelease];
   105 }
   106 
   107 - (NSString *)my_hexDump
   108 {
   109     NSMutableString *ret=[NSMutableString stringWithCapacity:[self length]*2];
   110     /* dumps size bytes of *data to string. Looks like:
   111      * [0000] 75 6E 6B 6E 6F 77 6E 20
   112      *                  30 FF 00 00 00 00 39 00 unknown 0.....9.
   113      * (in a single line of course)
   114      */
   115     unsigned int size= [self length];
   116     const unsigned char *p = [self bytes];
   117     unsigned char c;
   118     int n;
   119     char bytestr[4] = {0};
   120     char addrstr[10] = {0};
   121     char hexstr[ 16*3 + 5] = {0};
   122     char charstr[16*1 + 5] = {0};
   123     for(n=1;n<=size;n++) {
   124         if (n%16 == 1) {
   125             /* store address for this line */
   126             snprintf(addrstr, sizeof(addrstr), "%.4x",
   127                      ((unsigned int)p-(unsigned int)self) );
   128         }
   129         
   130         c = *p;
   131         if (isalnum(c) == 0) {
   132             c = '.';
   133         }
   134         
   135         /* store hex str (for left side) */
   136         snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
   137         strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
   138         
   139         /* store char str (for right side) */
   140         snprintf(bytestr, sizeof(bytestr), "%c", c);
   141         strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
   142         
   143         if(n%16 == 0) {
   144             /* line completed */
   145             //printf("[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
   146             [ret appendString:[NSString stringWithFormat:@"[%4.4s]   %-50.50s  %s\n",
   147                                addrstr, hexstr, charstr]];
   148             hexstr[0] = 0;
   149             charstr[0] = 0;
   150         } else if(n%8 == 0) {
   151             /* half line: add whitespaces */
   152             strncat(hexstr, "  ", sizeof(hexstr)-strlen(hexstr)-1);
   153             strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
   154         }
   155         p++; /* next byte */
   156     }
   157     
   158     if (strlen(hexstr) > 0) {
   159         /* print rest of buffer if not empty */
   160         //printf("[%4.4s]   %-50.50s  %s\n", addrstr, hexstr, charstr);
   161         [ret appendString:[NSString stringWithFormat:@"[%4.4s]   %-50.50s  %s\n",
   162                            addrstr, hexstr, charstr]];
   163     }
   164     return ret;
   165 }
   166 
   167 @end