美文网首页
扯淡的bug之字符数组

扯淡的bug之字符数组

作者: 7分醉 | 来源:发表于2016-02-26 15:28 被阅读67次

    char与unsigned char

    话不多说,先上代码。。。

        NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
        NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
    
        //输出到字符串
        static uint8_t buffer[1024];
        NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
    
        //调用加密接口
        [TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
            if (SUCCESS == code) {
                //成功,从buffer中获取数据
                NSString *str = [[NSString alloc] initWithCString:buffer encoding:NSUTF8StringEncoding];
                NSLog(@"成功!!!=%@", str);
            } else {
                //失败
                NSLog(@"失败 error=%hu", code);
            }
        }];
    

    这段代码调用接口方法进行加密,该方法主要有inputStream和outputStream,要加密的内容通过inputStream输入进去,加密结果通过outputStream输出,我们将输出流输出到一个buffer,调用成功后,从buffer中获取加密结果。
    思路完全正确,可是运行结束后从buffer中的到的却是null
    其原因就在下面这两行代码上

    static uint8_t buffer[1024];
    ...
    NSString *str = [[NSString alloc] initWithCString:buffer encoding:NSUTF8StringEncoding];
    

    其中

    typedef unsigned char uint8_t;
    - (nullable instancetype)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
    

    可以看出,其中的类型不同,一个是unsigned char 类型的 buffer 一个是要求 char 类型的,两者进行强制转换必定会丢失字符。所以导致 strnull

    对代码更改如下

        NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
        NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
    
        //输出到字符串
        static uint8_t buffer[1024];
        NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
    
        //调用加密接口
        [TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
            if (SUCCESS == code) {
                //成功,从buffer中获取数据
                NSData *data = [NSData dataWithBytes:buffer length:strlen(buffer)];
                //进行base64编码以方便显示
                data = [GTMBase64 encodeData:data];
                NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"成功!!!=%@", str);
            } else {
                //失败
                NSLog(@"失败 error=%hu", code);
            }
        }];
    

    静态数组的重复利用

    - (void)testFunction
    {
        NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
        NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
    
        //输出到字符串
        static uint8_t buffer[1024];
        //memset(buffer, 0, sizeof(uint8_t) * 1024);
        NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
    
        //调用加密接口
        [TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
            if (SUCCESS == code) {
                //成功,从buffer中获取数据
                NSData *data = [NSData dataWithBytes:buffer length:strlen(buffer)];
                //进行base64编码以方便显示
                data = [GTMBase64 encodeData:data];
                NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                NSLog(@"成功!!!=%@", str);
            } else {
                //失败
                NSLog(@"失败 error=%hu", code);
            }
        }];
    }
    

    将刚才的代码包装在一个方法里其好处是可以实现重复利用
    其中的 bufferstatic 类型,在重复利用的过程中,方法调用结束后第二次使用时 buffer 中还会保留上次的数据。

    所以如果在一个方法中有用到 static 来修饰,要明确是否真的需要在方法再次运行时使用之前保存的数据,如果不需要,请在方法开始时对 buffer 进行初始化,例如:
    memset(buffer, 0, sizeof(uint8_t) * 1024);
    使用 memset 进行内存初始化

    相关文章

      网友评论

          本文标题:扯淡的bug之字符数组

          本文链接:https://www.haomeiwen.com/subject/bkhwkttx.html