2011-01-29 67 views
5

我使用Apple的NSXMLParser类来加载数据。我有一个单独的框架来序列化我的数据。将NSString转换为Base64数据以进行XML序列化

我已经有足够的长冲刺,Word引号等出现在我的XML输出中,并在解析时导致错误,这通常会导致数据丢失,因为解析器对这些字符的处理不当。

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

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

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

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

回答

11

明白了。我使用的编码/解码方法,从这个回答我的NSString对象转换为NSData的对象,反之亦然: Any base64 library on iphone-sdk?

然后我写这些快捷的方法,即利用上述方法,并让我将Base64字符串数据写入XML。加载它的效果很好,已经用中文字符,单词字符等进行了测试。如果需要,也可以解析出来,但至少错误不在解析器中。 (这很容易导致数据丢失,如果你不妥善处理错误。)

+ (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方法。注意:我没有编写的代码,但多年来它一直运作良好:

+ (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: @"\n"]; 
     } 

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

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

    return result; 
} 
+1

我们有没有导入任何框架使用NSStringUtil ???? – 2012-09-06 11:58:02