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