data is nil when using base64 decoding in iPhone - iphone

Im parsing(JSON parsing) an image and tried to display in an image view.
I used the base64 decode method for decoding.
I used the below code for this:
NSString *base64String = responseObj.content;
NSData* data = [Base64 decode:base64String];
image.frame = CGRectMake(0, 0, 100, 100);
image.backgroundColor = [UIColor blueColor];
image.image = [UIImage imageWithData:data];
The Base64 class is
.h
#import <Foundation/Foundation.h>
#interface Base64 : NSObject {
}
+ (void) initialize;
+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length;
+ (NSString*) encode:(NSData*) rawBytes;
+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength;
+ (NSData*) decode:(NSString*) string;
#end
.m
static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char decodingTable[128];
+ (void) initialize {
if (self == [Base64 class]) {
memset(decodingTable, 0, ArrayLength(decodingTable));
for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) {
decodingTable[encodingTable[i]] = i;
}
}
}
+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length {
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
for (NSInteger i = 0; i < length; i += 3) {
NSInteger value = 0;
for (NSInteger j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger index = (i / 3) * 4;
output[index + 0] = encodingTable[(value >> 18) & 0x3F];
output[index + 1] = encodingTable[(value >> 12) & 0x3F];
output[index + 2] = (i + 1) < length ? encodingTable[(value >> 6) & 0x3F] : '=';
output[index + 3] = (i + 2) < length ? encodingTable[(value >> 0) & 0x3F] : '=';
}
return [[[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding] autorelease];
}
+ (NSString*) encode:(NSData*) rawBytes {
return [self encode:(const uint8_t*) rawBytes.bytes length:rawBytes.length];
}
+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength {
if ((string == NULL) || (inputLength % 4 != 0)) {
return nil;
}
while (inputLength > 0 && string[inputLength - 1] == '=') {
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}
return data;
}
+ (NSData*) decode:(NSString*) string {
return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] length:string.length];
}
#end
When i tried to see the contents of NSString it is showing the contents correctly.
But when i tried to see the contents of data it is showing
(NSData *) $2 = 0x00000000 .
Can anyone please tell me where I'm going wrong and why the data is nil.

i had a similar problem with some googled copy&paste base64 encoding method, so i would recommend to use QSUtilities:
This library provides general purposes libraries (string cleanup, net access, etc.) within Objective-C classes.
Take a look at the QSString Class

Try this:
NSString *base64String = responseObj.content;// U have base64 String
[Base64 initialize]; //U forgot this
NSData* data = [Base64 decode:base64String];
image.frame = CGRectMake(0, 0, 100, 100);
image.backgroundColor = [UIColor blueColor];
image.image = [UIImage imageWithData:data];

Related

iPhone - finalizing Apple's vague "VerificationController.m"

I am trying to implement the new VerificationController.m class that Apple released to fix the in-app purchase fraud problem.
As everything released by Apple, this is one more vague, incomplete and bad explained document with a lot of voids and unknowns that cannot be circumvented/understood by everyone.
I am trying to implement that, but at the end of the code we see these four methods:
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
#warning Replace this method.
return nil;
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
#warning Replace this method.
return nil;
}
#warning Implement this function.
char* base64_encode(const void* buf, size_t size)
{ return NULL; }
#warning Implement this function.
void * base64_decode(const char* s, size_t * data_len)
{ return NULL; }
You can see that Apple was lazy to implement the C functions at the end of the code. As my C/C++ abilities stink, I see I need to implement these two functions in C/C++ and that they must return char and void (???). Other people have posted routines to do that on SO, but they are either in Objective-C or not returning chars and void (??).
NOTE: this is another problem I have: how can a method return void if it is used by Apple in this form?
uint8_t *purchase_info_bytes = base64_decode([purchase_info_string cStringUsingEncoding:NSASCIIStringEncoding], &purchase_info_length);
shouldn't it be returning uint8_t?
NOTE2: another problem I have is that apple says base64_encode is required but it is not being used on the code provided by them. I think they are smoking bad stuff or my C/C++ knowledge really stink.
So, returning to my first question. Can someone post/point a method that can do the job that follows the requirements of the declared methods base64_encode and base64_decode? Please refrain from posting objective-c methods that are not compatible with these requirements imposed by Apple.
Thanks.
This solution should be pretty straight forward, which includes all the methods to populate the missing information. Tested and functional within the sandbox.
// single base64 character conversion
static int POS(char c)
{
if (c>='A' && c<='Z') return c - 'A';
if (c>='a' && c<='z') return c - 'a' + 26;
if (c>='0' && c<='9') return c - '0' + 52;
if (c == '+') return 62;
if (c == '/') return 63;
if (c == '=') return -1;
[NSException raise:#"invalid BASE64 encoding" format:#"Invalid BASE64 encoding"];
return 0;
}
- (NSString *)encodeBase64:(const uint8_t *)input length:(NSInteger)length
{
return [NSString stringWithUTF8String:base64_encode(input, (size_t)length)];
}
- (NSString *)decodeBase64:(NSString *)input length:(NSInteger *)length
{
size_t retLen;
uint8_t *retStr = base64_decode([input UTF8String], &retLen);
if (length)
*length = (NSInteger)retLen;
NSString *st = [[[NSString alloc] initWithBytes:retStr
length:retLen
encoding:NSUTF8StringEncoding] autorelease];
free(retStr); // If base64_decode returns dynamically allocated memory
return st;
}
char* base64_encode(const void* buf, size_t size)
{
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* str = (char*) malloc((size+3)*4/3 + 1);
char* p = str;
unsigned char* q = (unsigned char*) buf;
size_t i = 0;
while(i < size) {
int c = q[i++];
c *= 256;
if (i < size) c += q[i];
i++;
c *= 256;
if (i < size) c += q[i];
i++;
*p++ = base64[(c & 0x00fc0000) >> 18];
*p++ = base64[(c & 0x0003f000) >> 12];
if (i > size + 1)
*p++ = '=';
else
*p++ = base64[(c & 0x00000fc0) >> 6];
if (i > size)
*p++ = '=';
else
*p++ = base64[c & 0x0000003f];
}
*p = 0;
return str;
}
void* base64_decode(const char* s, size_t* data_len_ptr)
{
size_t len = strlen(s);
if (len % 4)
[NSException raise:#"Invalid input in base64_decode" format:#"%d is an invalid length for an input string for BASE64 decoding", len];
unsigned char* data = (unsigned char*) malloc(len/4*3);
int n[4];
unsigned char* q = (unsigned char*) data;
for(const char*p=s; *p; )
{
n[0] = POS(*p++);
n[1] = POS(*p++);
n[2] = POS(*p++);
n[3] = POS(*p++);
if (n[0]==-1 || n[1]==-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
if (n[2]==-1 && n[3]!=-1)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid BASE64 encoding"];
q[0] = (n[0] << 2) + (n[1] >> 4);
if (n[2] != -1) q[1] = ((n[1] & 15) << 4) + (n[2] >> 2);
if (n[3] != -1) q[2] = ((n[2] & 3) << 6) + n[3];
q += 3;
}
// make sure that data_len_ptr is not null
if (!data_len_ptr)
[NSException raise:#"Invalid input in base64_decode" format:#"Invalid destination for output string length"];
*data_len_ptr = q-data - (n[2]==-1) - (n[3]==-1);
return data;
}
Here is a base 64 encode function for NSString to NSString:
+(NSString *) encodeString:(NSString *)inString
{
NSData *data = [inString dataUsingEncoding:NSUTF8StringEncoding];
//Point to start of the data and set buffer sizes
int inLength = [data length];
int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
const char *inputBuffer = [data bytes];
char *outputBuffer = malloc(outLength);
outputBuffer[outLength] = 0;
//64 digit code
static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
//start the count
int cycle = 0;
int inpos = 0;
int outpos = 0;
char temp;
outputBuffer[outLength-1] = '=';
outputBuffer[outLength-2] = '=';
while (inpos < inLength){
switch (cycle) {
case 0:
outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
cycle = 1;
break;
case 1:
temp = (inputBuffer[inpos++]&0x03)<<4;
outputBuffer[outpos] = Encode[temp];
cycle = 2;
break;
case 2:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
temp = (inputBuffer[inpos++]&0x0F)<<2;
outputBuffer[outpos] = Encode[temp];
cycle = 3;
break;
case 3:
outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
cycle = 4;
break;
case 4:
outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
cycle = 0;
break;
default:
cycle = 0;
break;
}
}
NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
free(outputBuffer);
return pictemp;
}
and Here is a base 64 decode function for NSString to NSString:
+(NSString *) decodeString:(NSString *)inString
{
const char* string = [inString cStringUsingEncoding:NSASCIIStringEncoding];
NSInteger inputLength = inString.length;
static char decodingTable[128];
static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for (NSInteger i = 0; i < 128; i++) {
decodingTable[encodingTable[i]] = i;
}
if ((string == NULL) || (inputLength % 4 != 0)) {
return nil;
}
while (inputLength > 0 && string[inputLength - 1] == '=') {
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}
NSLog(#"%#",data);
NSString *finalString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return finalString;
}
These were pieced together from examples I found in various places on the internet when I was searching for them a while ago. They, may be easier for you to implement. I just created a Base64 class and placed these methods in it.
Here are the C wrappers around Justin's answer:
char* base64_encode(const void* buf, size_t size)
{
NSData* data = [NSData dataWithBytesNoCopy:(void*)buf length:size];
NSString* string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
return [[_Class_ encode:string] UTF8String];
}
void* base64_Decode (const char* s, size_t* data_len)
{
NSString* result = [_Class_ decode:[NSString stringWithCString:s encoding:NSASCIIStringEncoding]];
*data_len = result.length;
return [result UTF8String];
}
Where Class is the class that contains Justin's functions.

saving images in string format (to use in xml)..not working

i am converting image from picker into nsdata(jpeg representation) and then converting it into nsstring using the following code
NSData *data=UIImageJPEGRepresentation(image,1.0);
NSString *imageString=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
[[NSUserDefaults standardUserDefaults] setObject:imageString forKey:#"image_name"];
and at the other end where i need to display the image the uiimage is formed as follows.
NSString *imageString=[[NSString alloc] init];
imageString=[[NSUserDefaults standardUserDefaults] objectForKey:#"image_name"];
UIImage *image=[UIImage imageWithData:[imageString dataUsingEncoding:NSUTF8StringEncoding]];
the image variable used in the top code is not nil ,but the image formed from data is getting nil...when i nslogged userdefaults some string is present for the key mentioned above .can anyone explain why is this so..what is the right way to do this
If it goes through a web server or the like, you could encapsulate it with base64 enc/decoding or some other plain encoder.
It removes "bad" char, ie that screw up the string during transformation, and change them to generic alphabetical chars and then back again.
if this is the reason to your issues, here is a short one i use (which I most probably stole and adapted, but do not remember from whom. Sorry! :-) )
base64helper.h
#import <Foundation/Foundation.h>
#interface NSData (MBBase64)
base64helper.m
#import "base64helper.h"
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#implementation NSData (MBBase64)
+ (id)dataWithBase64EncodedString:(NSString *)string;
{
if (string == nil)
[NSException raise:NSInvalidArgumentException format:nil];
if ([string length] == 0)
return [NSData data];
static char *decodingTable = NULL;
if (decodingTable == NULL)
{
decodingTable = malloc(256);
if (decodingTable == NULL)
return nil;
memset(decodingTable, CHAR_MAX, 256);
NSUInteger i;
for (i = 0; i < 64; i++)
decodingTable[(short)encodingTable[i]] = i;
}
const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL) // Not an ASCII string!
return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (YES)
{
char buffer[4];
short bufferLength;
for (bufferLength = 0; bufferLength < 4; i++)
{
if (characters[i] == '\0')
break;
if (isspace(characters[i]) || characters[i] == '=')
continue;
buffer[bufferLength] = decodingTable[(short)characters[i]];
if (buffer[bufferLength++] == CHAR_MAX) // Illegal character!
{
free(bytes);
return nil;
}
}
if (bufferLength == 0)
break;
if (bufferLength == 1) // At least two characters are needed to produce one byte!
{
free(bytes);
return nil;
}
// Decode the characters in the buffer to bytes.
bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
if (bufferLength > 2)
bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
if (bufferLength > 3)
bytes[length++] = (buffer[2] << 6) | buffer[3];
}
realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}
- (NSString *)base64Encoding;
{
if ([self length] == 0)
return #"";
char *characters = malloc((([self length] + 2) / 3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [self length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [self length])
buffer[bufferLength++] = ((char *)[self bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
}
#end

-[NSCFDictionary length]: unrecognized selector

I have the next problem with this code:
NSDictionary * imagen = [[NSDictionary alloc] initWithDictionary:[envio resultValue]];
NSString *imagenS = [imagen valueForKey:#"/Result"];
[Base64 initialize];
NSData * imagenDecode = [Base64 decode:imagenS];
NSLog(#"%#", [imagenS length]);
//SAVE IMAGE
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#david.png",docDirectory];
[imagenDecode writeToFile:filePath atomically:YES];
[envio resultValue] --> return a NSDictionary with one image in Base 64 codification.
I want decoder and save this image but in my console I have showed this message:
2011-08-23 20:15:36.539 WSStub[39226:a0f] -[NSCFDictionary length]: unrecognized selector sent to instance 0xd00ee0
The Base 64 code is:
//
// Base64.m
// CryptTest
//
// Created by Kiichi Takeuchi on 4/20/10.
// Copyright 2010 ObjectGraph LLC. All rights reserved.
//
#import "Base64.h"
#implementation Base64
#define ArrayLength(x) (sizeof(x)/sizeof(*(x)))
static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char decodingTable[128];
+ (void) initialize
{
if (self == [Base64 class])
{
memset(decodingTable, 0, ArrayLength(decodingTable));
for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) {
decodingTable[encodingTable[i]] = i;
}
}
}
+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength
{
if ((string == NULL) || (inputLength % 4 != 0))
{
return nil;
}
while (inputLength > 0 && string[inputLength - 1] == '=')
{
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength)
{
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';
output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength)
{
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength)
{
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}
return data;
}
+ (NSData*) decode:(NSString*) string
{
return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] length:[string length]];
}
#end
The line
NSString *imagenS = [imagen valueForKey:#"/Result"];
is returning a dictionary, not a string. You'll have to inspect your data source to determine whether this is correct or not.
Your NSLog() call is wrong. To show a length, it should be:
NSLog(#"%lu", [imagenS length]);
But that is probably not the problem.
You seem to be invoking length on an NSDictionary. Hard to tell where you do that, since you don't show the piece of code where that happens. It could be that imagenS is not an NSString, but an NSDictionary instead.
Try to do:
NSLog(#"%#", [imagenS class]);
and see what is displayed. If probably tells you that imagenS is not a string, but an NSCFDictionary or similar instead.
FWIW, NSCFDictionary is one of the subclasses of NSDictionary that actually implement the different versions of the main class. This is called a class cluster.

(iphone) KERN_PROTECTION_FAILURE at ob_msgSend()

I'm fairly certain KER_PROTECTION_FAILURE is happening due to the following code.
(I don't get the error when I skip calling this function)
What I suspect is that the following code is wrong? (data can be gone before string object is released or something like that)
NSMutableData* data = [NSMutableData dataWithLength: dataLength];
// populate data
return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
Register $r0 shows the address of the returning NSString object.
and $r1 shows "release".
- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length {
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
int dataLength = ((length+2)/3)*4;
int remainder = dataLength % 16;
dataLength = dataLength + (16- remainder);
NSMutableData *data = [NSMutableData dataWithLength:
dataLength];
uint8_t *output = (uint8_t *)data.mutableBytes;
for (NSInteger i = 0; i < length; i += 3) {
NSInteger value = 0;
for (NSInteger j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger index = (i / 3) * 4;
output[index + 0] = table[(value >> 18) & 0x3F];
output[index + 1] = table[(value >> 12) & 0x3F];
output[index + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] :
'=';
output[index + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] :
'=';
}
return [[[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding]
autorelease]; }

iphone SDK : How Can I Convert a string to SHA-1 And SHA-1 to Base64? (for WSSecurity)

my convert code is all i have, but it converts a string to sha-1 to hex format. how can i convert sha-1 to base64 ?
-(NSString *)digest:(NSString*)input
int i;
const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:input.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
length:CC_SHA1_DIGEST_LENGTH];
for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
{
[output appendFormat:#"%02x", digest[i]];
}
return output;
}
There's no built-in hashing or Base64 in iOS. You'll have to roll your own. Find a C implementation of SHA1 in Google; as for Base64, I've got one for you:
NSString *ToBase64(NSData *d)
{
static const char ALPHABET[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const NSString *PAD1 = #"=", *PAD2 = #"==";
int l = [d length];
unsigned char *p = (unsigned char*)[d bytes];
unichar Chunk[4];
NSMutableString *s = [NSMutableString stringWithCapacity:(l+3)*4/3];
int i;
int mod = l % 3;
int ll = l - mod;
unsigned int triad;
NSString *sChunk;
for(i=0;i<ll;i+=3)
{
triad = (p[i]<<16) | (p[i+1]<<8) | p[i+2];
Chunk[0] = ALPHABET[(triad >> 18) & 0x3f];
Chunk[1] = ALPHABET[(triad >> 12) & 0x3f];
Chunk[2] = ALPHABET[(triad >> 6) & 0x3f];
Chunk[3] = ALPHABET[triad & 0x3f];
sChunk = [[NSString alloc] initWithCharacters:Chunk length:4];
[s appendString:sChunk];
[sChunk release];
}
if(mod == 1)
{
Chunk[0] = ALPHABET[(p[i] >> 2) & 0x3f];
Chunk[1] = ALPHABET[(p[i] << 4) & 0x3f];
sChunk = [[NSString alloc] initWithCharacters:Chunk length:2];
[s appendString:sChunk];
[sChunk release];
[s appendString: PAD2];
}
if(mod == 2)
{
triad = (p[i]<<8) | p[i+1];
Chunk[0] = ALPHABET[(triad >> 10) & 0x3f];
Chunk[1] = ALPHABET[(triad >> 4) & 0x3f];
Chunk[2] = ALPHABET[(triad << 2) & 0x3f];
sChunk = [[NSString alloc] initWithCharacters:Chunk length:3];
[s appendString:sChunk];
[sChunk release];
[s appendString: PAD1];
}
return s;
}