扯淡的bug之字符数组

2016-02-26  本文已影响67人  7分醉

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 进行内存初始化

上一篇下一篇

猜你喜欢

热点阅读