Converting file to Base64 URL safe encoding format in iOS

I am supposed to convert a file in to Base64 and add that String to a JSON which I am appending to a URL. The files that I am having are a .zip file and a text file with .info extension. The .info file is uploading correctly but with .zip file I am getting “Incorrect Padding” error as response from the server.

Below is my work;

- (void)uploadingData: (NSString *)fileName {

    NSArray *directoryPathsArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [directoryPathsArray objectAtIndex:0];

    NSString *absoluteFilePath = [NSString stringWithFormat:@"%@/%@/%@", documentsDirectory, baseDirName, fileName];

    NSInputStream *inputStream = [NSInputStream inputStreamWithFileAtPath:absoluteFilePath];
    [inputStream open];

    uint8_t buffer[1024];

    int len;

    NSMutableString *total = [[NSMutableString alloc] init];

    while ([inputStream hasBytesAvailable]) {
        len = [inputStream read:buffer maxLength:sizeof(buffer)];

        if (len > 0) {
             [total appendString: [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]];
        }
    }


    NSData *plainData = [total dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64String = [plainData base64EncodedStringWithOptions:0];

// Adding to JSON and upload goes here.
}

Where I have done the mistake?

Additionally, is there a way I can check the converted string is exactly according to Base64, before it append to JSON and upload to server?

Thanks

is base64 encoding url safe?

I’m using a node.bcrypt.js hash returning hex numbers in node.js for a password reset token. user.reset_password_token = require(‘crypto’).randomBytes(32).toString(‘hex’ ); Should I also base64 encod

Base64 Encoding safe for filenames?

Is Base64 encoding safe to use for filenames on windows and linux systems? From my research I have found replacing all / characters of the output string with – or _ should resolve any issues. Ca

Python: Converting file to base64 encoding

This is my code: import base64 with open(‘/Users/Bob/test.txt’) as f: encoded = base64.b64encode(f.readlines()) print(encoded) I’ve based it on the base64 documentation. However, when I try running i

Code for decoding/encoding a modified base64 URL

I want to base64 encode data to put it in a URL and then decode it within my HttpHandler. I have found that Base64 Encoding allows for a ‘/’ character which will mess up my UriTemplate matching. Then

iOS base64 encoding returning different result than php

I’m building an iOS app making use of our own web service but am having some issues when base64 encoding data within iOS and trying to compare it with the same data encoded using PHP base64_encode() f

IOS 7 base64 video encoding

I’m having an issue when I try to encode a video in base64 within iOS 7. I am not sure if my NSdata is being set correctly. The video is playing on my iOS simulator, it’s fine though. However when the

Unknown characters while converting encoded String to Base64 format

I need to decode the encoded string in my application. But while converting encoded string to Base64 format using the following method String base64 = new String(Base64.decode(encrypted, 0)); I am g

What character replacements should be performed to make base 64 encoding URL safe?

In looking at URL safe base 64 encoding, I’ve found it to be a very non-standard thing. Despite the copious number of built in functions that PHP has, there isn’t one for URL safe base 64 encoding. On

django – url pattern to match url safe base64 string

I am using import base64 string_for_url = base64.urlsafe_b64encode(string_to_format) but I’m not sure how to match the generated string in a url pattern. I found this regex: (?:[A-Za-z0-9+/]{4})*(?:

how to Read Base64 encode image file remotely

I have a image file which I uploaded to server using Base64 encoding(By converting to string). The server stored that string in a text file and gave me the url to that text file. Can anybody guide me

Answers

try this..

+ (NSString *)base64String:(NSString *)str
{
    NSData *theData = [str dataUsingEncoding: NSASCIIStringEncoding];
    const uint8_t* input = (const uint8_t*)[theData bytes];
    NSInteger length = [theData length];

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

    NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t* output = (uint8_t*)data.mutableBytes;

    NSInteger i;
    for (i=0; i < length; i += 3) {
        NSInteger value = 0;
        NSInteger j;
        for (j = i; j < (i + 3); j++) {
            value <<= 8;

            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }

        NSInteger theIndex = (i / 3) * 4;
        output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
        output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
        output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
        output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
    }

    return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}

I have found the mistakes as well as the answer. I do not need to convert the .zip file in to NSInputStream and I haven’t applied URL safe methods to the encoded string. Following is the way I have tackled it.

- (void)uploadingData: (NSString *)fileName {

    NSArray *directoryPathsArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [directoryPathsArray objectAtIndex:0];

    NSString *absoluteFilePath = [NSString stringWithFormat:@"%@/%@/%@", documentsDirectory, baseDirName, fileName];

    NSData *zipFileData = [NSData dataWithContentsOfFile:absoluteFilePath];

    NSString *base64String = [zipFileData base64EncodedStringWithOptions:0];

    base64String = [base64String stringByReplacingOccurrencesOfString:@"/"
                                                            withString:@"_"];

    base64String = [base64String stringByReplacingOccurrencesOfString:@"+"
                                                           withString:@"-"];

// Adding to JSON and upload goes here.
}

In Android there is a way to do both Base64 encoding and URL safe formatting with a single function.

byte[] bytes = Files.toByteArray(new File(sFileName));
byte[] encoded = Base64.encodeBase64URLSafe(bytes);

I have no idea whether there is a similar kind of easy way of doing it with iOS too.