4

Hello I am trying to figure out how convert / decode a base64 string in an iOS application to NSData, so I can decrypt the data that I encrypted.

The method I used for converting the NSData to a base 64 string can be found here Is there a similar way to create method to decode / convert the base 64 string to NSData?

Community
  • 1
  • 1
ipatch
  • 3,933
  • 8
  • 60
  • 99
  • 1
    Unfortunately iOS SDK doesn't provide anything to encode/decode BASE64. Is there any issue with the code you found? There are many example code about base64 in objective-c. here is one I used before: http://stackoverflow.com/questions/392464/any-base64-library-on-iphone-sdk – mask8 Aug 18 '12 at 16:43

1 Answers1

14

This is what I was looking for.

+ (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;
}
ipatch
  • 3,933
  • 8
  • 60
  • 99
  • Remember to mark this as accepted so this question doesn't end up in the unanswered column. – CodaFi Aug 18 '12 at 18:51
  • Normally good ethics to cite where you got this code. I'm a fan of giving credit where credit is due. Stumbled upon the exact same code written by @alpha09jp [here](http://stackoverflow.com/a/3947315/931452) though its possible s/he copy/pasted it elsewhere so I'm not sure if that user wrote it or not. – Russ Nov 29 '12 at 17:22
  • Upon further inspection there are a few differences between the two scripts, but the variable names and structure are at least 95% identical. – Russ Nov 29 '12 at 17:33
  • Another (shorter) implementation here: https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L54 – Sam Dec 18 '12 at 02:23
  • 1
    Updated link (fixed to commit): https://github.com/AFNetworking/AFNetworking/blob/4f6d61fe54be07e0744fd12a3fe2bc29527fcbc0/AFNetworking/AFURLRequestSerialization.m#L29 @ChrisCirefice – Sam Nov 20 '13 at 00:45