2011-01-29 68 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