• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Base-64 decode (was Property List Editor)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Base-64 decode (was Property List Editor)


  • Subject: Re: Base-64 decode (was Property List Editor)
  • From: Steven Spencer <email@hidden>
  • Date: Mon, 13 Jun 2005 00:33:09 +0100


It's a little after the event, however the following code might still be useful.
Data spanning to 76 bytes per line (MIME) is left as an exercise for the reader.


  - Steve Spencer


Class Header ------------

#import <Foundation/Foundation.h>


@interface NSData (Extensions)

+ (NSData *)dataWithBase64Data:(NSData *)base64Data;
- (NSData *)initWithBase64Data:(NSData *)base64Data;
- (NSData *)base64EncodedData;

@end


Class -----

#import "dataExtensions.h"


@implementation NSData (Extensions)

const unsigned char Base64Pad = '=';
const unsigned char Base64Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static unsigned char Base64Decode[255];


+ (void)initialize
{
  //Build decode table
  unsigned int index;

  for (index = 0; index < 255; index++)
    Base64Decode[index] = 0;

  for (index = 0; index < 64; index++)
    Base64Decode[Base64Encode[index]] = index;
}


+ (NSData *)dataWithBase64Data:(NSData *)base64Data
{
return [[[[self class] alloc] initWithBase64Data:base64Data] autorelease];
}


- (NSData *)initWithBase64Data:(NSData *)base64Data
{
unsigned char *inputBuffer = (unsigned char *)[base64Data bytes], *outputBuffer;
unsigned int inputLength = [base64Data length];
unsigned int outputRemainder = 3, index, inputQuads;
unsigned char q1, q2, q3, q4;
NSMutableData *outputData;


  if (inputLength >= 4 && 0 == inputLength %4) {
    inputQuads = inputLength / 4;

    if (Base64Pad == inputBuffer[inputLength -1]) {
      inputQuads--;
      outputRemainder--;
    }

    if (Base64Pad == inputBuffer[inputLength -2])
      outputRemainder--;

outputData = [NSMutableData dataWithLength:(inputQuads * 3) + outputRemainder];
outputBuffer = [outputData mutableBytes];


    for (index = 0; index < inputQuads; index++) {
      q1 = Base64Decode[*inputBuffer++];
      q2 = Base64Decode[*inputBuffer++];
      q3 = Base64Decode[*inputBuffer++];
      q4 = Base64Decode[*inputBuffer++];
      *outputBuffer++ = q1 << 2 | (q2 & 0x30) >> 4;
      *outputBuffer++ = (q2 & 0xF) << 4 | (q3 & 0x3C) >> 2;
      *outputBuffer++ = (q3 & 0x3) << 6 | (q4 & 0x3F);
    }

    if (2 == outputRemainder) {
      q1 = Base64Decode[*inputBuffer++];
      q2 = Base64Decode[*inputBuffer++];
      q3 = Base64Decode[*inputBuffer++];
      *outputBuffer++ = q1 << 2 | (q2 & 0x30) >> 4;
      *outputBuffer++ = (q2 & 0xF) << 4 | (q3 & 0x3C) >> 2;

    } else if (1 == outputRemainder) {
      q1 = Base64Decode[*inputBuffer++];
      q2 = Base64Decode[*inputBuffer++];
      *outputBuffer++ = q1 << 2 | (q2 & 0x30) >> 4;
    }

    return [self initWithData:outputData];
  }

  return [self initWithData:[NSData data]];
}


- (NSData *)base64EncodedData; { unsigned int inputTriplets = [self length] / 3; unsigned int inputRemainder = [self length] % 3; unsigned int outputLength = inputTriplets * 4; unsigned int index; unsigned char *outputBuffer, *inputBuffer; unsigned char t1, t2, t3; NSMutableData *outputData;

  if (0 != inputRemainder) outputLength += 4;

  outputData = [NSMutableData dataWithLength:outputLength];
  outputBuffer = [outputData mutableBytes];
  inputBuffer = (unsigned char *)[self bytes];

  for (index = 0; index < inputTriplets; index++) {
    t1 = *inputBuffer++;
    t2 = *inputBuffer++;
    t3 = *inputBuffer++;
    *outputBuffer++ = Base64Encode[t1 >> 2];
    *outputBuffer++ = Base64Encode[(t1 & 0x3) << 4 | t2 >> 4];
    *outputBuffer++ = Base64Encode[(t2 & 0xF) << 2 | t3 >> 6];
    *outputBuffer++ = Base64Encode[t3 & 0x3F];
  }

  if (2 == inputRemainder) {
    t1 = *inputBuffer++;
    t2 = *inputBuffer++;
    *outputBuffer++ = Base64Encode[t1 >> 2];
    *outputBuffer++ = Base64Encode[(t1 & 0x3) << 4 | t2 >> 4];
    *outputBuffer++ = Base64Encode[(t2 & 0xF) << 2];
    *outputBuffer++ = Base64Pad;

  } else if (1 == inputRemainder) {
    t1 = *inputBuffer++;
    *outputBuffer++ = Base64Encode[t1 >> 2];
    *outputBuffer++ = Base64Encode[(t1 & 0x3) << 4];
    *outputBuffer++ = Base64Pad;
    *outputBuffer++ = Base64Pad;
  }

  return [outputData copy];
}

@end


Test Programme --------------

#import <Foundation/Foundation.h>
#import "dataExtensions.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    //Source
    NSString *src = @"The quick brown fox jumps over the lazy dog.";
    NSLog(@"%@", src);
    NSData *srcData = [src dataUsingEncoding:NSASCIIStringEncoding];

//Encode
NSData *base64Data = [srcData base64EncodedData];
NSString *tgt = [[[NSString alloc] initWithData:base64Data encoding:NSASCIIStringEncoding] autorelease];
NSLog(@"%@", tgt);


//Decode
NSData *decoded = [NSData dataWithBase64Data:base64Data];
NSString *rev = [[[NSString alloc] initWithData:decoded encoding:NSASCIIStringEncoding] autorelease];
NSLog(@"%@", rev);


    [pool release];
    return 0;
}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Prev by Date: Re: how to make an NSWindow unmovable...
  • Next by Date: Tableview with checkboxes for bidirectional to-many relationship
  • Previous by thread: Re: Base-64 decode (was Property List Editor)
  • Next by thread: NSMutableDictionary setObject:forKey:
  • Index(es):
    • Date
    • Thread