将 NSString 转换为 Base64 数据以进行 XML 序列化 [英] Converting NSString to Base64 Data for XML Serialization

查看:28
本文介绍了将 NSString 转换为 Base64 数据以进行 XML 序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Apple 的 NSXMLParser 类来加载数据.我有一个单独的框架来序列化我的数据.

I use Apple's NSXMLParser class to load data. I have a separate framework for serializing my data.

我已经受够了 XML 输出中出现的长破折号、Word 引号等,并在解析时导致错误,这通常会由于解析器对这些字符的处理不当而导致数据丢失.

I've had enough of the long dash, the Word quotes, etc. showing up in my XML output and causing errors when parsing, which often result in data loss due to the parser's poor handling of those characters.

如果我有一个用户输入作为 NSString 对象,我想将它转换为 Base64(我有一个实用方法),然后将这些字节写入 XML 文件,代替 NSString.我知道这可能会占用更多空间,但至少我不必再处理验证问题了.

If I have a user's input as an NSString object, I want to convert it to Base64 (which I have a utility method for), then write those bytes to the XML file, in place of the NSString. I understand this might take up more space, but at least I won't have to deal with the validation issues any more.

我的问题是,如何将 NSData 字节(在 NSLog 语句中看起来像 <8d72...>)转换为 NSString,没有 使用编码取回原始值.我希望将出现在日志语句中的那些实际字节转换为 NSString.最后(当加载这个序列化数据时),如果你有一个 NSString:

My question is, how does one go about converting the NSData bytes (which look like <8d72...> in an NSLog statement) to an NSString, without using encoding to get the original value back. I want those actual bytes, as they appear in the log statement, to be converted to an NSString. And finally (when loading this serialized data), if you have an NSString:

NSString *loadedData = @"8d72...";

如何从这种形式转变为人类可读的格式?整个编码过程对我来说有点难以理解,但我认为这是确保奇怪的用户输入正确保存在我的 XML 文件中的一种非常可靠的方法.

How does one go from this form to the human-readable format? The whole encoding process is a little difficult for me to understand, but I think this is a really solid way to ensure that weird user input is properly persisted in my XML files.

推荐答案

明白了.我正在使用此答案中的编码/解码方法将我的 NSString 对象转换为 NSData 对象,反之亦然:iphone-sdk 上的任何 base64 库?

Got it. I'm using the encoding/decoding methods from this answer to convert my NSString objects to NSData objects, and vice versa: Any base64 library on iphone-sdk?

然后我写了这些利用上述方法的快速方法,并允许我将Base64字符串数据写入XML.加载起来效果很好,已经用汉字、Word 字符等进行了测试.如果你愿意,你也可以解析这些,但至少错误不在解析器中.(如果错误处理不当,很容易导致数据丢失.)

And then I wrote these quick methods that make use of the above methods, and allow me to write the Base64 string data to XML. Loading it up works great, has been tested with Chinese characters, Word characters, etc. You can also parse these out if you want, but at least the error isn't in the parser. (Which could easily result in data loss if you don't handle the errors properly.)

+ (NSString *)toBase64String:(NSString *)string {
    NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding];

    NSString *ret = [NSStringUtil base64StringFromData:data length:[data length]];

    return ret;
}

+ (NSString *)fromBase64String:(NSString *)string {
    NSData  *base64Data = [NSStringUtil base64DataFromString:string];

    NSString* decryptedStr = [[NSString alloc] initWithData:base64Data encoding:NSUnicodeStringEncoding];

    return [decryptedStr autorelease];
}

由于原始链接已关闭,我搜索了一段时间前的代码,这里是我上面提到的 NSStringUtil 方法.请注意,此代码不是我创作的,但多年来一直运行良好:

As the original link is down, I hunted down my code from a while ago, here are my NSStringUtil methods mentioned above. Note I did not author this code, but it has been working well for years:

+ (NSData *)base64DataFromString: (NSString *)string {
    unsigned long ixtext, lentext;
    unsigned char ch, input[4], output[3];
    short i, ixinput;
    Boolean flignore, flendtext = false;
    const char *temporary;
    NSMutableData *result;

    if (!string) {
        return [NSData data];
    }

    ixtext = 0;

    temporary = [string UTF8String];

    lentext = [string length];

    result = [NSMutableData dataWithCapacity: lentext];

    ixinput = 0;

    while (true) {
        if (ixtext >= lentext) {
            break;
        }

        ch = temporary[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 ctcharsinput = 3;
            Boolean flbreak = false;

            if (flendtext) {
                if (ixinput == 0) {
                    break;
                }

                if ((ixinput == 1) || (ixinput == 2)) {
                    ctcharsinput = 1;
                } else {
                    ctcharsinput = 2;
                }

                ixinput = 3;

                flbreak = true;
            }

            input[ixinput++] = ch;

            if (ixinput == 4) {
                ixinput = 0;

                unsigned char0 = input[0];
                unsigned char1 = input[1];
                unsigned char2 = input[2];
                unsigned char3 = input[3];

                output[0] = (char0 << 2) | ((char1 & 0x30) >> 4);
                output[1] = ((char1 & 0x0F) << 4) | ((char2 & 0x3C) >> 2);
                output[2] = ((char2 & 0x03) << 6) | (char3 & 0x3F);

                for (i = 0; i < ctcharsinput; i++) {
                    [result appendBytes: &output[i] length: 1];
                }
            }

            if (flbreak) {
                break;
            }
        }
    }

    return result;
}

+ (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)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 < 1) {
        return @"";
    }

    result = [NSMutableString stringWithCapacity: lentext];

    raw = [data bytes];

    ixtext = 0;

    while (true) {
        ctremaining = lentext - ixtext;

        if (ctremaining <= 0) {
            break;
        }

        for (i = 0; i < 3; i++) { 
            unsigned long ix = ixtext + i;

            if (ix < lentext) {
                input[i] = raw[ix];
            } else {
                input[i] = 0;
            }
        }

        output[0] = (input[0] & 0xFC) >> 2;
        output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
        output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
        output[3] = input[2] & 0x3F;

        ctcopy = 4;

        switch (ctremaining) {
            case 1: 
                ctcopy = 2;
                break;
            case 2: 
                ctcopy = 3;
                break;
        }

        for (i = 0; i < ctcopy; i++) {
            [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
        }

        for (i = ctcopy; i < 4; i++) {
            [result appendString: @"="];
        }

        ixtext += 3;
        charsonline += 4;

        if ((ixtext % 90) == 0) {
            [result appendString: @"
"];
        }

        if (length > 0) {
            if (charsonline >= length) {
                charsonline = 0;

                [result appendString: @"
"];
            }
        }
    }

    return result;
}

这篇关于将 NSString 转换为 Base64 数据以进行 XML 序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆