如何将NSData转换为NSString十六进制字符串?当我调用-description一个NSData对象时,我看到一个NSData对象字节的十六进制字符串,如:<f6e7cd28 0fc5b5d4 88f8394b af216506 bc1bba86 4d5b483d>我希望将数据的这种表示(减去lt / gt引号)放入内存中,NSString这样我就可以使用它。我不想调用-[NSData description]然后只修剪lt / gt引号(因为我认为这不是NSData公共界面的保证方面,并且将来会发生变化。将NSData对象表示为NSString对象(除了调用之外-description)的最简单方法是什么?
3 回答
繁星点点滴滴
TA贡献1803条经验 获得超3个赞
请记住,任何String(format: ...)
解决方案都会非常慢(对于大数据)
NSData *data = ...;NSUInteger capacity = data.length * 2;NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity];const unsigned char *buf = data.bytes;NSInteger i;for (i=0; i<data.length; ++i) { [sbuf appendFormat:@"%02X", (NSUInteger)buf[i]];}
如果你需要更高性能的东西试试这个:
static inline char itoh(int i) { if (i > 9) return 'A' + (i - 10); return '0' + i;}NSString * NSDataToHex(NSData *data) { NSUInteger i, len; unsigned char *buf, *bytes; len = data.length; bytes = (unsigned char*)data.bytes; buf = malloc(len*2); for (i=0; i<len; i++) { buf[i*2] = itoh((bytes[i] >> 4) & 0xF); buf[i*2+1] = itoh(bytes[i] & 0xF); } return [[NSString alloc] initWithBytesNoCopy:buf length:len*2 encoding:NSASCIIStringEncoding freeWhenDone:YES];}
Swift 4.2版本
extension Data { var hexString: String? { return withUnsafeBytes { (bytes: UnsafePointer<UInt8>) in let charA = UInt8(UnicodeScalar("a").value) let char0 = UInt8(UnicodeScalar("0").value) func itoh(_ value: UInt8) -> UInt8 { return (value > 9) ? (charA + value - 10) : (char0 + value) } let hexLen = count * 2 let ptr = UnsafeMutablePointer<UInt8>.allocate(capacity: hexLen) for i in 0 ..< count { ptr[i*2] = itoh((bytes[i] >> 4) & 0xF) ptr[i*2+1] = itoh(bytes[i] & 0xF) } return String(bytesNoCopy: ptr, length: hexLen, encoding: .utf8, freeWhenDone: true) } }}
哔哔one
TA贡献1854条经验 获得超8个赞
我同意解决方案不要调用description
哪个是保留用于调试,所以好点和好问题:)
最简单的解决方案是循环遍历字节NSData
并从中构造NSString。使用[yourData bytes]
访问字节,并建立串入一个NSMutableString
。
以下是使用NSData类别实现此示例的示例
@interface NSData(Hex)-(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces;@end@implementation NSData(Hex)-(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces{ const unsigned char* bytes = (const unsigned char*)[self bytes]; NSUInteger nbBytes = [self length]; //If spaces is true, insert a space every this many input bytes (twice this many output characters). static const NSUInteger spaceEveryThisManyBytes = 4UL; //If spaces is true, insert a line-break instead of a space every this many spaces. static const NSUInteger lineBreakEveryThisManySpaces = 4UL; const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces; NSUInteger strLen = 2*nbBytes + (spaces ? nbBytes/spaceEveryThisManyBytes : 0); NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen]; for(NSUInteger i=0; i<nbBytes; ) { [hex appendFormat:@"%02X", bytes[i]]; //We need to increment here so that the every-n-bytes computations are right. ++i; if (spaces) { if (i % lineBreakEveryThisManyBytes == 0) [hex appendString:@"\n"]; else if (i % spaceEveryThisManyBytes == 0) [hex appendString:@" "]; } } return [hex autorelease];}@end
用法:
NSData* data = ...NSString* hex = [data hexRepresentationWithSpaces_AS:YES];
添加回答
举报
0/150
提交
取消