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