求助:如何获取NSData的最后2个十六进制字符?subdataWithRange无效
解决NSData获取最后两个十六进制字符的问题
嘿,我懂你碰到的麻烦了——想用subdataWithRange提取NSData最后两个十六进制字符却没得到预期结果对吧?先理清楚核心逻辑:NSData里的1个字节对应2个十六进制字符,所以你要的最后两位十六进制(比如示例里的63),本质就是取NSData的最后1个字节,再把它转换成两位十六进制字符串就行。
为什么subdataWithRange可能没达到预期?
你之前用这个方法没成功,大概率是因为直接拿到了最后1个字节的NSData对象,但没把它转换成对应的十六进制字符串——毕竟NSData本身不是字符串,直接打印它的描述是系统帮你转的十六进制,但你需要主动把字节值转成字符串格式。
具体解决方案
这里给两种实用的实现方式:
方法1:用subdataWithRange取最后字节再转字符串
先通过subdataWithRange拿到最后1个字节的NSData,再把字节值提取出来格式化:
NSData *originalData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding]; // 对应<616263> if (originalData.length >= 1) { // 取最后1个字节的NSData NSData *lastByteData = [originalData subdataWithRange:NSMakeRange(originalData.length - 1, 1)]; // 提取字节值并转成两位十六进制字符串 uint8_t byteValue; [lastByteData getBytes:&byteValue length:1]; NSString *lastHexChars = [NSString stringWithFormat:@"%02x", byteValue]; NSLog(@"%@", lastHexChars); // 输出:63 }
方法2:直接操作字节指针(更高效)
跳过subdata的创建,直接从NSData的字节数组里取最后一个元素:
NSData *originalData = [@"abc" dataUsingEncoding:NSUTF8StringEncoding]; if (originalData.length > 0) { const uint8_t *bytes = originalData.bytes; uint8_t lastByte = bytes[originalData.length - 1]; NSString *lastHexChars = [NSString stringWithFormat:@"%02x", lastByte]; NSLog(@"%@", lastHexChars); // 输出:63 }
扩展:取更多最后N个十六进制字符
如果之后需要取最后4个(即最后2个字节),只需要调整范围,然后循环拼接每个字节的十六进制字符串:
NSData *originalData = [@"abcd" dataUsingEncoding:NSUTF8StringEncoding]; // 对应<61626364> NSUInteger hexCount = 4; // 要取的十六进制字符数,对应2个字节 if (originalData.length >= hexCount/2) { NSUInteger startIndex = originalData.length - (hexCount/2); NSData *targetData = [originalData subdataWithRange:NSMakeRange(startIndex, hexCount/2)]; NSMutableString *hexString = [NSMutableString string]; const uint8_t *bytes = targetData.bytes; for (NSUInteger i = 0; i < targetData.length; i++) { [hexString appendFormat:@"%02x", bytes[i]]; } NSLog(@"%@", hexString); // 输出:6364 }
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

