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 |
*/
|