Skip to content

Instantly share code, notes, and snippets.

@danielphillips
Last active December 17, 2016 03:42
Show Gist options
  • Select an option

  • Save danielphillips/3907443 to your computer and use it in GitHub Desktop.

Select an option

Save danielphillips/3907443 to your computer and use it in GitHub Desktop.

Revisions

  1. danielphillips revised this gist Jul 26, 2013. 1 changed file with 7 additions and 3 deletions.
    10 changes: 7 additions & 3 deletions NSString+Crypto.m
    Original file line number Diff line number Diff line change
    @@ -105,8 +105,12 @@ + (NSString *)encodeBase64WithData:(NSData *)objData {
    // Terminate the string-based result
    *objPointer = '\0';

    NSString *resultString = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];

    free(strResult);

    // Return the results as an NSString object
    return [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];
    return resultString;
    }

    + (NSData *)decodeBase64WithString:(NSString *)strBase64 {
    @@ -115,7 +119,7 @@ + (NSData *)decodeBase64WithString:(NSString *)strBase64 {
    int intCurrent;
    int i = 0, j = 0, k;

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

    // Run through the whole string, converting as we go
    @@ -185,4 +189,4 @@ + (NSData *)decodeBase64WithString:(NSString *)strBase64 {
    }


    @end
    @end
  2. danielphillips created this gist Oct 17, 2012.
    13 changes: 13 additions & 0 deletions NSString+Crypto.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    #import <Foundation/Foundation.h>
    #import <CommonCrypto/CommonHMAC.h>

    @interface NSString (Crypto)

    - (NSString *)md5;
    + (NSString *)encodeBase64WithString:(NSString *)strData;
    + (NSString *)encodeBase64WithData:(NSData *)objData;
    + (NSData *)decodeBase64WithString:(NSString *)strBase64;
    - (NSString*)sha1;
    - (NSString*)base64;

    @end
    188 changes: 188 additions & 0 deletions NSString+Crypto.m
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,188 @@
    #import "NSString+Crypto.h"

    @implementation NSString (Crypto)

    - (NSString *) md5
    {
    const char *cStr = [self UTF8String];
    unsigned char result[16];
    CC_MD5( cStr, strlen(cStr), result ); // This is the md5 call
    return [NSString stringWithFormat:
    @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
    result[0], result[1], result[2], result[3],
    result[4], result[5], result[6], result[7],
    result[8], result[9], result[10], result[11],
    result[12], result[13], result[14], result[15]
    ];
    }

    -(NSString*)sha1{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];

    uint8_t digest[CC_SHA1_DIGEST_LENGTH];

    CC_SHA1(data.bytes, data.length, digest);

    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02x", digest[i]];


    return output;

    }

    -(NSString*)base64{
    return [NSString encodeBase64WithString:self];
    }

    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
    };


    + (NSString *)encodeBase64WithString:(NSString *)strData {
    return [NSString 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, 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';

    // Return the results as an NSString object
    return [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding];
    }

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

    unsigned char * objResult;
    objResult = calloc(intLength, sizeof(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;
    }


    @end