【问题标题】:How to use NULL character with NSString?如何在 NSString 中使用 NULL 字符?
【发布时间】:2010-01-21 18:23:11
【问题描述】:

在 PHP 中,我可以调用 base64_encode("\x00". $username. "\x00". $password) 并且 "\x00" 代表一个 NULL 字符。

现在,在 Objective-C 中,我有一个函数可以将 NSData 转换为 DaveDribin 创建的base64 encoded NSString

如何从包含 NULL 字符的字符串创建数据?

这似乎不起作用...

NSData * authCode = [[NSString stringWithFormat:@"%c%@%c%@", '\0', self.username, '\0', self.password] dataUsingEncoding:NSUTF8StringEncoding];

【问题讨论】:

  • 请描述“不起作用”
  • 为什么你的字符串包含 NUL 字符?这听起来有点像一开始就应该是 NSData 的东西。

标签: objective-c character-encoding nsstring


【解决方案1】:

像这样:

char bytes[] = "\0username\0password";
NSData * data = [NSData dataWithBytes:bytes length:sizeof(bytes)];

NSLog(@"%@", data);

输出:

2010-01-22 09:15:22.546 app[6443] <00757365 726e616d 65007061 7373776f 726400>

或来自NSString

char bytes[] = "\0username\0password";
NSString * string = [[NSString alloc] initWithBytes:bytes length:sizeof(bytes) encoding:NSUTF8StringEncoding];
NSData * data = [string dataUsingEncoding:NSUTF8StringEncoding];

您可以在开头、用户名/密码之间和结尾看到空字节 - 因为 char[] 以空结尾。

【讨论】:

  • 您将字符串初始化两次(使用[NSString string]initWithBytes:length:)。此外,您可能需要使用initWithBytes:length:encoding: 来实际构建。
  • 更正了 +string 与 -init 组合的错误初始化,因为作为公认的答案,人们将复制此代码和错误。
【解决方案2】:

你的语法是正确的。 NSString 只是不能很好地处理 NULL 字节。我找不到任何关于它的文档,但是 NSString 会默默地忽略带有 0 参数的 %c 格式说明符(并且在那张纸条上,字符常量 '\0' 扩展为整数 0;这是正确的)。但是,它可以处理直接嵌入到 NSString 文字中的 \0

查看此代码:

#import <Cocoa/Cocoa.h>
int main (int argc, char const *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *stringByChars = [NSString stringWithFormat:@"-%c%c%c%c-",0,0,0,0];
    NSString *stringByEscapes = [NSString stringWithFormat:@"-\0\0\0\0-"];
    NSLog(@"  stringByChars: \"%@\"", stringByChars);
    NSLog(@"            len: %d", [stringByChars length]);
    NSLog(@"           data: %@", [stringByChars dataUsingEncoding:NSUTF8StringEncoding]);
    NSLog(@"stringByEscapes: \"%@\"", stringByEscapes);
    NSLog(@"            len: %d", [stringByEscapes length]);
    NSLog(@"           data: %@", [stringByEscapes dataUsingEncoding:NSUTF8StringEncoding]);
    [pool drain];
    return 0;
}

返回:

  stringByChars: "--"
            len: 2
           data: <2d2d>
stringByEscapes: "-
            len: 6
           data: <2d000000 002d>

(请注意,由于stringByEscapes 实际上包含NULL 字节,它会提前终止NSLog 字符串。

【讨论】:

    【解决方案3】:

    不太清楚为什么会这样,但不要使用 @"%c" 作为带有 '\0' 的格式字符串,而是尝试使用 @"%@" 作为带有 @"\0" 的格式字符串

    【讨论】:

      【解决方案4】:

      你也可以试试这个(测试和工作 - 取自:http://www.cocoabuilder.com/archive/cocoa/174917-nul-characters-in-nsstring-cause-unexpected-results.html

      NSString* s1 = [[NSString alloc] initWithBytes:buffer length:sizeof (buffer)
            encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16LE)]; // @"A[NUL]end" (*)
      NSLog(@"s1 = %@", s1);
      NSString* s2 = @"CD";
      NSLog(@"s2 = %@", s2) ;
      NSString* sC = [s1 stringByAppendingString:s2];
      NSLog(@"sC = %@", sC);
      NSLog(@"length of s1:%i", [s1 length]);
      NSLog(@"length of s2:%i", [s2 length]);
      NSLog(@"length of sC:%i", [sC length]);
      [s1 release];
      

      【讨论】:

        【解决方案5】:

        stefanB's answer 看起来是一个正确的选择。原来我传递了错误的信息,使它看起来像 \0 没有工作

        没关系:

        [NSString stringWithFormat:@"\0user\0pass"]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-19
          • 1970-01-01
          • 1970-01-01
          • 2014-08-14
          • 1970-01-01
          • 1970-01-01
          • 2013-03-17
          • 1970-01-01
          相关资源
          最近更新 更多