0

我试图加密可能包含中文字符的数据,但是当我解密字符串时我一直为空。我加密数据的方式来自我们的 android 团队,所以我想保持不变。当我调用 [[NSString alloc] initWithData:dataFrom64 encoding:NSUTF8StringEncoding]; 它给了我一个 UTF8String 的 NSString 表示。当我调用 NSString UTF8String 时,它返回了一些意想不到的东西。我试图打印出所有的东西,看看哪里出了问题。对不起,混乱。我真的需要这方面的帮助。我不知道如何解决它。

   NSLog(@"--------Test begins--------");
   NSString *chinese = @"abcd 測試";

   /** encrypt **/
   char const *testCStr = [testString UTF8String];
   char const *cStr = [chinese UTF8String];
   char *newCStr = (char*)calloc(sizeof(char), strlen(cStr));
   strcpy(newCStr, cStr);

   int lenStr = strlen(cStr);
   int lenKey = testString.length;

   for (int i = 0, j = 0; i < lenStr; i++, j++) {
      if (j >= lenKey) j = 0;
      newCStr[i] = cStr[i] ^ testCStr[j];
   }

   NSString *tempStr = [NSString stringWithUTF8String:[[NSString stringWithFormat:@"%s",newCStr] UTF8String]];
   NSData   *tempData = [tempStr dataUsingEncoding:NSUTF8StringEncoding];
   NSString *base64Str = [tempData base64EncodedString];
   char const *dataCStr = [tempData bytes];
   NSString* dataToStr = [[NSString alloc] initWithData:tempData
                                          encoding:NSUTF8StringEncoding];

   NSLog(@"chinese         : %@", chinese);
   NSLog(@"chinese utf8    : %s ", [chinese UTF8String]);
   NSLog(@"encrypted utf8  : %s ", newCStr);
   NSLog(@"--------Encrypt--------");
   NSLog(@"encrypted str   : %@", tempStr);
   NSLog(@"temp data bytes : %s", dataCStr);
   NSLog(@"data to str     : %@", dataToStr);
   NSLog(@"base64 data     : %@", base64Str);
   NSLog(@"data temp       : %@", tempData );

   /** decrypt**/
   NSData *dataFrom64 = [NSData dataFromBase64String:base64Str];
   NSString *strFromData = [[NSString alloc] initWithData:dataFrom64
                                             encoding:NSUTF8StringEncoding];
   char const *cStrFromData = [strFromData UTF8String];
   char *newStr2 = (char*)calloc(sizeof(char), strlen(cStrFromData));

   strcpy(newStr2, cStrFromData);

   for (int i = 0, j = 0; i < lenStr; i++, j++) {
      if (j >= lenKey) j = 0;
      newStr2[i] = cStrFromData[i] ^ testCStr[j];
   }

   NSLog(@"--------Decrypt--------");
   NSLog(@"data 64         : %@", dataFrom64 );
   NSLog(@"data 64 bytes   : %s", [dataFrom64 bytes]);
   NSLog(@"str from data   : %@", strFromData);
   NSLog(@"cStr from data  : %s", [strFromData UTF8String]);
   NSLog(@"decrypt utf8    : %s", newStr2);
   NSLog(@"decrypt str     : %@", [NSString stringWithUTF8String:newStr2]);

这是输出:

   --------Test begins--------
   chinese         : abcd 測試
   chinese utf8    : abcd 測試 
   encrypted utf8  : #!B5aºÄõ–ôá 
   --------Encrypt--------
   encrypted str   : #!B5aºÄõ–ôá
   temp data bytes : #!B5aºÄõ–ôá6.889 WebSocke
   data to str     : #!B5aºÄõ–ôá
   base64 data     : IyFCNWHCusOEw7XigJPDtMOh
   data temp       : <23214235 61c2bac3 84c3b5e2 8093c3b4 c3a1>
   --------Decrypt--------
   data 64         : <23214235 61c2bac3 84c3b5e2 8093c3b4 c3a1>
   data 64 bytes   : #!B5aºÄõ–ôá
   str from data   : #!B5aºÄõ–ôá
   cStr from data  : #!B5aºÄõ–ôá
   decrypt utf8    : abcd òÇÙºÛî‚Äì√¥√°
   decrypt str     : (null)
   --------test ends--------
4

1 回答 1

1

问题是它newCStr不是以 null 结尾的,也不代表有效的 UTF-8 字符串。所以这个转换

NSString *tempStr = [NSString stringWithUTF8String:[[NSString stringWithFormat:@"%s",newCStr] UTF8String]];

一定会失败(或给出错误的结果)。

以下代码避免了不必要的转换:

NSLog(@"--------Test begins--------");
NSString *plainText = @"abcd 測試";
NSString *keyString = @"topsecret";

/** encrypt **/
NSMutableData *plainData = [[plainText dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t *plainBytes = [plainData mutableBytes];
const uint8_t *keyBytes = [keyData bytes];
for (int i = 0, j = 0; i < [plainData length]; i++, j++) {
    if (j >= [keyData length]) j = 0;
    plainBytes[i] ^= keyBytes[j];
}
NSString *base64Str = [plainData base64EncodedString];

NSLog(@"chinese         : %@", plainText);
NSLog(@"--------Encrypt--------");
NSLog(@"base64 data     : %@", base64Str);

/** decrypt**/
NSData *dataFrom64 = [NSData dataFromBase64String:base64Str];

NSMutableData *decodeData = [dataFrom64 mutableCopy];
uint8_t *decodeBytes = [decodeData mutableBytes];
for (int i = 0, j = 0; i < [decodeData length]; i++, j++) {
    if (j >= [keyData length]) j = 0;
    decodeBytes[i] ^= keyBytes[j];
}
NSString *decrypted = [[NSString alloc] initWithData:decodeData
                                              encoding:NSUTF8StringEncoding];
NSLog(@"--------Decrypt--------");
NSLog(@"decrypt str     : %@", decrypted);

输出:

--------测试开始--------
Chinese : abcd 测试
-  -  -  - 加密 -  -  -  - 
base64 数据:FQ0TF0WFysmc3ck=
--------解密--------
解密 str : abcd 测试
于 2013-08-30T11:04:59.230 回答