Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>This is a good use case for Objective C <a href="http://en.wikipedia.org/wiki/Objective-C#Categories" rel="noreferrer">categories</a>.</p> <p>For Base64 encoding:</p> <pre><code>#import &lt;Foundation/NSString.h&gt; @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 &lt; 1) return @""; result = [NSMutableString stringWithCapacity: lentext]; raw = [data bytes]; ixtext = 0; while (true) { ctremaining = lentext - ixtext; if (ctremaining &lt;= 0) break; for (i = 0; i &lt; 3; i++) { unsigned long ix = ixtext + i; if (ix &lt; lentext) input[i] = raw[ix]; else input[i] = 0; } output[0] = (input[0] &amp; 0xFC) &gt;&gt; 2; output[1] = ((input[0] &amp; 0x03) &lt;&lt; 4) | ((input[1] &amp; 0xF0) &gt;&gt; 4); output[2] = ((input[1] &amp; 0x0F) &lt;&lt; 2) | ((input[2] &amp; 0xC0) &gt;&gt; 6); output[3] = input[2] &amp; 0x3F; ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i &lt; ctcopy; i++) [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]]; for (i = ctcopy; i &lt; 4; i++) [result appendString: @"="]; ixtext += 3; charsonline += 4; if ((length &gt; 0) &amp;&amp; (charsonline &gt;= length)) charsonline = 0; } return result; } @end </code></pre> <p>For Base64 decoding:</p> <pre><code>#import &lt;Foundation/Foundation.h&gt; @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 &gt;= lentext) { break; } ch = tempcstring [ixtext++]; flignore = false; if ((ch &gt;= 'A') &amp;&amp; (ch &lt;= 'Z')) { ch = ch - 'A'; } else if ((ch &gt;= 'a') &amp;&amp; (ch &lt;= 'z')) { ch = ch - 'a' + 26; } else if ((ch &gt;= '0') &amp;&amp; (ch &lt;= '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] &lt;&lt; 2) | ((inbuf[1] &amp; 0x30) &gt;&gt; 4); outbuf[1] = ((inbuf[1] &amp; 0x0F) &lt;&lt; 4) | ((inbuf[2] &amp; 0x3C) &gt;&gt; 2); outbuf[2] = ((inbuf[2] &amp; 0x03) &lt;&lt; 6) | (inbuf[3] &amp; 0x3F); for (i = 0; i &lt; ctcharsinbuf; i++) { [theData appendBytes: &amp;outbuf[i] length: 1]; } } if (flbreak) { break; } } } return theData; } @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload