简体   繁体   English

在NSInputStream中使用base64编码

[英]Using base64 encoding with NSInputStream

I'm using RNCryptor to crypt files and for large files I use NSInputStream to separate file into chunks and to encode / decode those chunks. 我正在使用RNCryptor加密文件,对于大文件,我使用NSInputStream将文件分为多个块并进行编码/解码。 It worked great until I needed to base64 encode / decode chunks which are passed to streams. 直到我需要对传递到流的块进行base64编码/解码为止,它的效果都很好。

Following code works perfectly fine for encoding, except it doesn't do base64 encoding: 下面的代码可以很好地进行编码,但是它不会执行base64编码:

  NSInputStream *tmpStream = [[NSInputStream alloc] initWithURL:fileURL];
    NSOutputStream *outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];

    [tmpStream open];
    [outputStream open];

    __block NSMutableData *data = [NSMutableData dataWithLength:kBlockSize];
    __block RNEncryptor *encryptor = nil;

    dispatch_block_t readStreamBlock = ^{
        [data setLength:kBlockSize];
        NSInteger bytesRead = [tmpStream read:[data mutableBytes] maxLength:kBlockSize];

        if (bytesRead < 0) {

            NSLog(@"An error occurred while decrypting file stream");
            if (resultBlock) { resultBlock(nil); }
            return;
        }
        else if (bytesRead == 0){
            [encryptor finish];
        }
        else {
            [data setLength:bytesRead];
            [encryptor addData:data];
        }
    };

    encryptor = [[RNEncryptor alloc] initWithSettings:kRNCryptorAES256Settings
                                             password:HUCryptorPassword
                                              handler:^(RNCryptor *cryptor, NSData *data) {

                                                    [outputStream write:data.bytes maxLength:data.length];

                                                    if(cryptor.isFinished){

                                                        [outputStream close];

                                                        if (resultBlock) {
                                                            resultBlock([NSString stringWithFormat:@"%@", filePath]);
                                                        }
                                                    }
                                                    else {
                                                        readStreamBlock();
                                                    }
                                                }];
    readStreamBlock();

I tried adding base64 encoding after the data is encrypted and before writing to output stream: 在数据加密之后和写入输出流之前,我尝试添加base64编码:

NSData *base64Data = [data base64EncodedDataWithOptions:kNilOptions]; //Tried with all options
[outputStream write:base64Data.bytes maxLength:base64Data.length];

But that gives me incorrect results in output file. 但这给了我输出文件中不正确的结果。

Only correct way I get correctly encoded / decoded data is to load whole file in memory and call encode / decode methods. 获得正确编码/解码数据的唯一正确方法是将整个文件加载到内存中,并调用编码/解码方法。

NSData *resultData = [NSData dataWithContentsOfFile:filePath]; //This is location of output file stream
NSData *encodedData = [resultData base64EncodedDataWithOptions:kNilOptions]; //Gives me correct base64 encoded data

I want to avoid that since I need to make encoding / decoding big files, such as videos, sounds and images. 我想避免这种情况,因为我需要对大文件(例如视频,声音和图像)进行编码/解码。

Is there any safe way to accomplish this? 有没有安全的方法可以做到这一点?

4 base64 characters fit in three bytes. 3个字节可容纳4个base64字符。

When encoding make sure you encode chunks of 4 characters, holding over any remainder for the next portion of the stream. 编码时,请确保对4个字符的块进行编码,保留流的下一部分的任何剩余部分。 As the end of the stream encode what is left. 在流的末尾编码剩下的内容。 Base64 pads the end of data that is not mod4, that is the "=" characters at the end. Base64填充不是mod4的数据的末尾,即末尾的“ =”字符。

For decoding decode in chunks that are mod3 encoded characters in length. 对于解码,以块为长度进行解码,这些块的长度为mod3编码字符。

If you set it up so that you encode in 3 block (or multiples or 3) then the base64 encoding will also fall on a boundary. 如果将其设置为以3块(或3或3的倍数)进行编码,则base64编码也将落在边界上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM