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
|