How do I do base64 encoding on iOS?

IosObjective CBase64

Ios Problem Overview


I'd like to do base64 encoding and decoding, but I could not find any support from the iPhone SDK. How can I do base64 encoding and decoding with or without a library?

Ios Solutions


Solution 1 - Ios

This is a good use case for Objective C categories.

For Base64 encoding:

#import <Foundation/NSString.h>

@interface NSString (NSStringAdditions)

+ (NSString *) base64StringFromData:(NSData *)data length:(int)length;

@end

-------------------------------------------

#import "NSStringAdditions.h"

static char base64EncodingTable[64] = {
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};

@implementation NSString (NSStringAdditions)

+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {
  unsigned long ixtext, lentext;
  long ctremaining;
  unsigned char input[3], output[4];
  short i, charsonline = 0, ctcopy;
  const unsigned char *raw;
  NSMutableString *result;

  lentext = [data length]; 
  if (lentext < 1)
    return @"";
  result = [NSMutableString stringWithCapacity: lentext];
  raw = [data bytes];
  ixtext = 0; 

  while (true) {
    ctremaining = lentext - ixtext;
    if (ctremaining <= 0) 
       break;        
    for (i = 0; i < 3; i++) { 
       unsigned long ix = ixtext + i;
       if (ix < lentext)
          input[i] = raw[ix];
       else
  input[i] = 0;
  }
  output[0] = (input[0] & 0xFC) >> 2;
  output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
  output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
  output[3] = input[2] & 0x3F;
  ctcopy = 4;
  switch (ctremaining) {
    case 1: 
      ctcopy = 2; 
      break;
    case 2: 
      ctcopy = 3; 
      break;
  }
    
  for (i = 0; i < ctcopy; i++)
     [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
    
  for (i = ctcopy; i < 4; i++)
     [result appendString: @"="];
    
  ixtext += 3;
  charsonline += 4;
   
  if ((length > 0) && (charsonline >= length))
    charsonline = 0;
  }     
  return result;
}

@end

For Base64 decoding:

#import <Foundation/Foundation.h>

@class NSString;

@interface NSData (NSDataAdditions)

+ (NSData *) base64DataFromString:(NSString *)string;

@end

-------------------------------------------

#import "NSDataAdditions.h"

@implementation NSData (NSDataAdditions)

+ (NSData *)base64DataFromString: (NSString *)string
{
	unsigned long ixtext, lentext;
	unsigned char ch, inbuf[4], outbuf[3];
	short i, ixinbuf;
	Boolean flignore, flendtext = false;
	const unsigned char *tempcstring;
	NSMutableData *theData;
	
	if (string == nil)
	{
		return [NSData data];
	}
	
	ixtext = 0;
	
	tempcstring = (const unsigned char *)[string UTF8String];
	
	lentext = [string length];
	
	theData = [NSMutableData dataWithCapacity: lentext];
	
	ixinbuf = 0;
 
	while (true)
	{
		if (ixtext >= lentext)
		{
			break;
		}
		
		ch = tempcstring [ixtext++];
			
		flignore = false;
	
		if ((ch >= 'A') && (ch <= 'Z'))
		{
			ch = ch - 'A';
		}
		else if ((ch >= 'a') && (ch <= 'z'))
		{
			ch = ch - 'a' + 26;
		}
		else if ((ch >= '0') && (ch <= '9'))
		{
			ch = ch - '0' + 52;
		}
		else if (ch == '+')
		{
			ch = 62;
		}
		else if (ch == '=')
		{
			flendtext = true;
		}
		else if (ch == '/')
		{
			ch = 63;
		}
		else
		{
			flignore = true; 
		}
		
		if (!flignore)
		{
			short ctcharsinbuf = 3;
			Boolean flbreak = false;
			 
			if (flendtext)
			{
				if (ixinbuf == 0)
				{
					break;
				}
				
				if ((ixinbuf == 1) || (ixinbuf == 2))
				{
					ctcharsinbuf = 1;
				}
				else
				{
					ctcharsinbuf = 2;
				}
				
				ixinbuf = 3;
			
				flbreak = true;
			}
		
			inbuf [ixinbuf++] = ch;
		
			if (ixinbuf == 4)
			{
				ixinbuf = 0;
			
				outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
				outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
				outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
	
				for (i = 0; i < ctcharsinbuf; i++)
				{
					[theData appendBytes: &outbuf[i] length: 1];
				}
			}
		
			if (flbreak)
			{
				break;
			}
		}
	}
 
	return theData;
}

    @end

Solution 2 - Ios

A really, really fast implementation which was ported (and modified/improved) from the PHP Core library into native Objective-C code is available in the QSStrings Class from the QSUtilities Library. I did a quick benchmark: a 5.3MB image (JPEG) file took < 50ms to encode, and about 140ms to decode.

The code for the entire library (including the Base64 Methods) are available on GitHub.

Or alternatively, if you want the code to just the Base64 methods themselves, I've posted it here:

First, you need the mapping tables:

static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const short _base64DecodingTable[256] = {
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
    -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
};

To Encode:

+ (NSString *)encodeBase64WithString:(NSString *)strData {
    return [QSStrings encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]];
}

+ (NSString *)encodeBase64WithData:(NSData *)objData {
    const unsigned char * objRawData = [objData bytes];
    char * objPointer;
    char * strResult;

    // Get the Raw Data length and ensure we actually have data
    int intLength = [objData length];
    if (intLength == 0) return nil;

    // Setup the String-based Result placeholder and pointer within that placeholder
    strResult = (char *)calloc((((intLength + 2) / 3) * 4) + 1, sizeof(char));
    objPointer = strResult;
    
    // Iterate through everything
    while (intLength > 2) { // keep going until we have less than 24 bits
        *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
        *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
        *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
        *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];
        
        // we just handled 3 octets (24 bits) of data
        objRawData += 3;
        intLength -= 3; 
    }

    // now deal with the tail end of things
    if (intLength != 0) {
        *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
        if (intLength > 1) {
            *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
            *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
            *objPointer++ = '=';
        } else {
            *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
            *objPointer++ = '=';
            *objPointer++ = '=';
        }
    }

    // Terminate the string-based result
    *objPointer = '\0';

    // Create result NSString object
    NSString *base64String = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];

    // Free memory
    free(strResult);

    return base64String;
}

To Decode:

+ (NSData *)decodeBase64WithString:(NSString *)strBase64 {
    const char *objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding];
    size_t intLength = strlen(objPointer);
    int intCurrent;
    int i = 0, j = 0, k;

    unsigned char *objResult = calloc(intLength, sizeof(unsigned char));

    // Run through the whole string, converting as we go
    while ( ((intCurrent = *objPointer++) != '\0') && (intLength-- > 0) ) {
        if (intCurrent == '=') {
            if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) {
                // the padding character is invalid at this point -- so this entire string is invalid
                free(objResult);
                return nil;
            }
            continue;
        }

        intCurrent = _base64DecodingTable[intCurrent];
        if (intCurrent == -1) {
            // we're at a whitespace -- simply skip over
            continue;
        } else if (intCurrent == -2) {
            // we're at an invalid character
            free(objResult);
            return nil;
        }

        switch (i % 4) {
            case 0:
                objResult[j] = intCurrent << 2;
                break;

            case 1:
                objResult[j++] |= intCurrent >> 4;
                objResult[j] = (intCurrent & 0x0f) << 4;
                break;

            case 2:
                objResult[j++] |= intCurrent >>2;
                objResult[j] = (intCurrent & 0x03) << 6;
                break;

            case 3:
                objResult[j++] |= intCurrent;
                break;
        }
        i++;
    }

    // mop things up if we ended on a boundary
    k = j;
    if (intCurrent == '=') {
        switch (i % 4) {
            case 1:
                // Invalid state
                free(objResult);
                return nil;

            case 2:
                k++;
                // flow through
            case 3:
                objResult[k] = 0;
        }
    }

    // Cleanup and setup the return NSData
    NSData * objData = [[[NSData alloc] initWithBytes:objResult length:j] autorelease];
    free(objResult);
    return objData;
}

Solution 3 - Ios

At the time this question was originally posted, people were understandably directing you to third-party base 64 libraries because of the lack of any native routines. But iOS 7 introduced base 64 encoding routines (which actually simply just exposes private methods iOS had going back to iOS 4).

So, you can use the NSData method base64EncodedStringWithOptions: to create a base-64 string from a NSData.

NSString *string = [data base64EncodedStringWithOptions:kNilOptions];

And you can use initWithBase64EncodedString:options: to convert a base-64 string back to a NSData:

NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions]; 

Or, in Swift:

let string = data.base64EncodedString()

And

let data = Data(base64Encoded: string)

Solution 4 - Ios

iOS includes built in support for base64 encoding and decoding. If you look at resolv.h you should see the two functions b64_ntop and b64_pton . The Square SocketRocket library provides a reasonable example of how to use these functions from objective-c.

These functions are pretty well tested and reliable - unlike many of the implementations you may find in random internet postings. Don't forget to link against libresolv.dylib.

Solution 5 - Ios

Since this seems to be the number one google hit on base64 encoding and iphone, I felt like sharing my experience with the code snippet above.

It works, but it is extremely slow. A benchmark on a random image (0.4 mb) took 37 seconds on native iphone. The main reason is probably all the OOP magic - single char NSStrings etc, which are only autoreleased after the encoding is done.

Another suggestion posted here (ab)uses the openssl library, which feels like overkill as well.

The code below takes 70 ms - that's a 500 times speedup. This only does base64 encoding (decoding will follow as soon as I encounter it)

+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {
int lentext = [data length]; 
if (lentext < 1) return @"";

char *outbuf = malloc(lentext*4/3+4); // add 4 to be sure

if ( !outbuf ) return nil;

const unsigned char *raw = [data bytes];

int inp = 0;
int outp = 0;
int do_now = lentext - (lentext%3);

for ( outp = 0, inp = 0; inp < do_now; inp += 3 )
{
	outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
	outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
	outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
	outbuf[outp++] = base64EncodingTable[raw[inp+2] & 0x3F];
}

if ( do_now < lentext )
{
	char tmpbuf[2] = {0,0};
	int left = lentext%3;
	for ( int i=0; i < left; i++ )
	{
		tmpbuf[i] = raw[do_now+i];
	}
	raw = tmpbuf;
	outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
	outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
	if ( left == 2 ) outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
}

NSString *ret = [[[NSString alloc] initWithBytes:outbuf length:outp encoding:NSASCIIStringEncoding] autorelease];
free(outbuf);

return ret;
}

I left out the line-cutting since I didn't need it, but it's trivial to add.

For those who are interested in optimizing: the goal is to minimize what happens in the main loop. Therefore all logic to deal with the last 3 bytes is treated outside the loop.

Also, try to work on data in-place, without additional copying to/from buffers. And reduce any arithmetic to the bare minimum.

Observe that the bits that are put together to look up an entry in the table, would not overlap when they were to be orred together without shifting. A major improvement could therefore be to use 4 separate 256 byte lookup tables and eliminate the shifts, like this:

outbuf[outp++] = base64EncodingTable1[(raw[inp] & 0xFC)];
outbuf[outp++] = base64EncodingTable2[(raw[inp] & 0x03) | (raw[inp+1] & 0xF0)];
outbuf[outp++] = base64EncodingTable3[(raw[inp+1] & 0x0F) | (raw[inp+2] & 0xC0)];
outbuf[outp++] = base64EncodingTable4[raw[inp+2] & 0x3F];

Of course you could take it a whole lot further, but that's beyond the scope here.

Solution 6 - Ios

In mvds's excellent improvement, there are two problems. Change code to this:

raw = tmpbuf;
inp = 0;
outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
if ( left == 2 ) outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
else outbuf[outp++] = '=';
outbuf[outp++] = '=';

Solution 7 - Ios

Better solution :

There is a built in function in NSData

[data base64Encoding]; //iOS < 7.0
[data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength]; //iOS >= 7.0

Solution 8 - Ios

Glad people liked it. The end-game was a little flawed I must admit. Besides rightly setting inp=0 you should either also increase tmpbuf's size to 3, like

unsigned char tmpbuf[3] = {0,0,0};

or leave out the orring of raw[inp+2]; if we would have a raw[inp+2] != 0 for this chunk we would still be in the loop of course...

Either way works, you might consider keeping the final table lookup block identical to the one in the loop for clarity. In the final version I used I did

while ( outp%4 ) outbuf[outp++] = '=';

To add the ==

Sorry I didn't check RFC's and stuff, should have done a better job!

Solution 9 - Ios

Under iOS8 and later use - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options of NSData

Solution 10 - Ios

#import "NSDataAdditions.h"
@implementation NSData (NSDataAdditions)

+ (NSData *) base64DataFromString: (NSString *)string {
  unsigned long ixtext, lentext;
  unsigned char ch, input[4], output[3];
  short i, ixinput;
  Boolean flignore, flendtext = false;
  const char *temporary;
  NSMutableData *result;
  
  if (!string)
    return [NSData data];
  
  ixtext = 0;
  temporary = [string UTF8String];
  lentext = [string length];
  result = [NSMutableData dataWithCapacity: lentext];
  ixinput = 0;
  
  while (true) {
    if (ixtext >= lentext)
      break;
    ch = temporary[ixtext++];
    flignore = false;
    
    if ((ch >= 'A') && (ch <= 'Z'))
      ch = ch - 'A';
    else if ((ch >= 'a') && (ch <= 'z'))
      ch = ch - 'a' + 26;
    else if ((ch >= '0') && (ch <= '9'))
      ch = ch - '0' + 52;
    else if (ch == '+')
      ch = 62;
    else if (ch == '=')
      flendtext = true;
    else if (ch == '/')
      ch = 63;
    else
      flignore = true;
    
    if (!flignore) {
      short ctcharsinput = 3;
      Boolean flbreak = false;
      
      if (flendtext) {
         if (ixinput == 0)
           break;              
         if ((ixinput == 1) || (ixinput == 2))
           ctcharsinput = 1;
         else
           ctcharsinput = 2;
         ixinput = 3;
         flbreak = true;
      }
      
      input[ixinput++] = ch;
      
      if (ixinput == 4){
        ixinput = 0;
        output[0] = (input[0] << 2) | ((input[1] & 0x30) >> 4);
        output[1] = ((input[1] & 0x0F) << 4) | ((input[2] & 0x3C) >> 2);
        output[2] = ((input[2] & 0x03) << 6) | (input[3] & 0x3F);
        for (i = 0; i < ctcharsinput; i++)
        [result appendBytes: &output[i] length: 1];
      }
    if (flbreak)
      break;
    }
  }
  return result;
}
@end

Solution 11 - Ios

For an update to use the NSData (NSDataBase64Encoding) category methods in iOS7 see my answer here: https://stackoverflow.com/a/18927627/1602729

Solution 12 - Ios

Here's a compact Objective-C version as a Category on NSData. It takes some thinking about...

@implementation NSData (DataUtils)

static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

- (NSString *)newStringInBase64FromData
{
 NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
 unsigned char * working = (unsigned char *)[self bytes];
 int srcLen = [self length];
 
 // tackle the source in 3's as conveniently 4 Base64 nibbles fit into 3 bytes
 for (int i=0; i<srcLen; i += 3)
 {
  // for each output nibble
  for (int nib=0; nib<4; nib++)
  {
   // nibble:nib from char:byt
   int byt = (nib == 0)?0:nib-1;
   int ix = (nib+1)*2;
   
   if (i+byt >= srcLen) break;
   
   // extract the top bits of the nibble, if valid
   unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F);

   // extract the bottom bits of the nibble, if valid
   if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F);
   
   [dest appendFormat:@"%c", base64[curr]];
  }
 }
 
 return dest;
}

@end

Padding can be added if required by making the scope of 'byt' wider and appending 'dest' with (2-byt) "=" characters before returning.

A Category can then be added to NSString, thus:

@implementation NSString (StringUtils)

- (NSString *)newStringInBase64FromString
{
 NSData *theData = [NSData dataWithBytes:[self UTF8String] length:[self length]]; 
 
 return [theData newStringInBase64FromData];
}

@end

Solution 13 - Ios

iOS has had built-in Base64 encoding and decoding methods (without using libresolv) since iOS 4. However, it was only declared in the iOS 7 SDK. Apple documentation states that you can use it when targeting iOS 4 and above.

NSData *myData = ... some data
NSString *base64String = [myData base64Encoding];
NSData *decodedData = [[NSData alloc] initWithBase64Encoding:base64String];

Solution 14 - Ios

Here is an example to convert an NSData object to Base 64. It also shows how to go the other way (decode a base 64 encoded NSData object):

NSData *dataTake2 = 
  [@"iOS Developer Tips" dataUsingEncoding:NSUTF8StringEncoding];
 
// Convert to Base64 data
NSData *base64Data = [dataTake2 base64EncodedDataWithOptions:0];
 
// Do something with the data...
 
// Now convert back from Base64
NSData *nsdataDecoded = [base64Data initWithBase64EncodedData:base64Data options:0];

Solution 15 - Ios

in iOS 7

        NSData *data=[[NSData alloc]init];
        [data base64Encoding];

Solution 16 - Ios

I have done it using the following class..

@implementation Base64Converter
static char base64EncodingTable[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',  'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',    '8', '9', '+', '/'
};
+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {

unsigned long ixtext, lentext;

long ctremaining;

unsigned char input[3], output[4];

short i, charsonline = 0, ctcopy;

const unsigned char *raw;

NSMutableString *result;

lentext = [data length];

if (lentext < 1)
    return @"";

result = [NSMutableString stringWithCapacity: lentext];

raw = [data bytes];

ixtext = 0;

while (true) {
    
    ctremaining = lentext - ixtext;
    
    if (ctremaining <= 0)
        break;
    
    for (i = 0; i < 3; i++) {
        unsigned long ix = ixtext + i;
        if (ix < lentext)
            input[i] = raw[ix];
        else
            input[i] = 0;
    }
    
    output[0] = (input[0] & 0xFC) >> 2;
    
    output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
    
    output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
    
    output[3] = input[2] & 0x3F;
    
    ctcopy = 4;
    
    switch (ctremaining) {
        case 1:
            ctcopy = 2;
            break;
            
        case 2:
            ctcopy = 3;
            break;
    }
    
    for (i = 0; i < ctcopy; i++)
        [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
    
    for (i = ctcopy; i < 4; i++)
        [result appendString: @"="];
    
    ixtext += 3;
    
    charsonline += 4;
    
    if ((length > 0) && (charsonline >= length))
        charsonline = 0;
}
return result;
}
@end

While calling call

 [Base64Converter base64StringFromData:dataval length:lengthval];

That's it...

Solution 17 - Ios

I Think This will be helpful

 + (NSString *)toBase64String:(NSString *)string {
    NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding];
    
    NSString *ret = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    
    return ret;
    }
    
    + (NSString *)fromBase64String:(NSString *)string {
NSData *aData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSData *aDataDecoded = [[NSData alloc]initWithBase64EncodedString:string options:0];
NSString *decryptedStr = [[NSString alloc]initWithData:aDataDecoded encoding:NSUTF8StringEncoding];

return [decryptedStr autorelease];

}

Solution 18 - Ios

Download Base64

Do following code to convert an image to base64

NSString *base64String=[UIImagePNGRepresentation(image) base64Encoding];

Solution 19 - Ios

As per your requirement i have created a sample demo using Swift 4 in which you can encode/decode string and image as per your requirement.

  • I have also added sample methods of relevant operations.

      //
      //  Base64VC.swift
      //  SOF_SortArrayOfCustomObject
      //
      //  Created by Test User on 09/01/18.
      //  Copyright © 2018 Test User. All rights reserved.
      //
    
      import UIKit
      import Foundation
    
      class Base64VC: NSObject {
          
          //----------------------------------------------------------------
          // MARK:-
          // MARK:- String to Base64 Encode Methods
          //----------------------------------------------------------------
          
          func sampleStringEncodingAndDecoding() {
              if let base64String = self.base64Encode(string: "TestString") {
                  print("Base64 Encoded String: \n\(base64String)")
                  if let originalString = self.base64Decode(base64String: base64String) {
                      print("Base64 Decoded String: \n\(originalString)")
                  }
              }
          }
          
          
          //----------------------------------------------------------------
          
          func base64Encode(string: String) -> String? {
              if let stringData = string.data(using: .utf8) {
                  return stringData.base64EncodedString()
              }
              return nil
          }
          
          //----------------------------------------------------------------
          
          func base64Decode(base64String: String) -> String? {
              if let base64Data = Data(base64Encoded: base64String) {
                  return String(data: base64Data, encoding: .utf8)
              }
              return nil
          }
          
          
          //----------------------------------------------------------------
          // MARK:-
          // MARK:- Image to Base64 Encode  Methods
          //----------------------------------------------------------------
          
          func sampleImageEncodingAndDecoding() {
              if let base64ImageString = self.base64Encode(image: UIImage.init(named: "yourImageName")!) {
                  print("Base64 Encoded Image: \n\(base64ImageString)")
                  if let originaImage = self.base64Decode(base64ImageString: base64ImageString) {
                      print("originalImageData \n\(originaImage)")
                  }
              }
          }
          
          //----------------------------------------------------------------
          
          func base64Encode(image: UIImage) -> String? {
              if let imageData = UIImagePNGRepresentation(image) {
                  return imageData.base64EncodedString()
              }
              return nil
          }
          
          //----------------------------------------------------------------
          
          func base64Decode(base64ImageString: String) -> UIImage? {
              if let base64Data = Data(base64Encoded: base64ImageString) {
                  return UIImage(data: base64Data)!
              }
              return nil
          }
          
          
      }
    

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBlueDolphinView Question on Stackoverflow
Solution 1 - IosAlex ReynoldsView Answer on Stackoverflow
Solution 2 - IosMike HoView Answer on Stackoverflow
Solution 3 - IosRobView Answer on Stackoverflow
Solution 4 - IosquellishView Answer on Stackoverflow
Solution 5 - IosmvdsView Answer on Stackoverflow
Solution 6 - Iosuser335742View Answer on Stackoverflow
Solution 7 - IosNagarajView Answer on Stackoverflow
Solution 8 - IosmvdsView Answer on Stackoverflow
Solution 9 - IosAlexeyVMPView Answer on Stackoverflow
Solution 10 - Iosalpha09jpView Answer on Stackoverflow
Solution 11 - IosDamien PontifexView Answer on Stackoverflow
Solution 12 - Iosuser503771View Answer on Stackoverflow
Solution 13 - Iosuser102008View Answer on Stackoverflow
Solution 14 - IosJohn MuchowView Answer on Stackoverflow
Solution 15 - IosManiView Answer on Stackoverflow
Solution 16 - IosDurai Amuthan.HView Answer on Stackoverflow
Solution 17 - IosMrugView Answer on Stackoverflow
Solution 18 - IosPankaj WadhwaView Answer on Stackoverflow
Solution 19 - IosMobile Team iOS-RNView Answer on Stackoverflow