NSData를 NSString Hex 문자열로 변환하는 방법은 무엇입니까?
내가 전화를 할 때 -description
온 NSData
객체, 나는 꽤 진수 문자열 참조 NSData
객체의 바이트 등이 :
<f6e7cd28 0fc5b5d4 88f8394b af216506 bc1bba86 4d5b483d>
이 데이터 표현 (lt / gt 따옴표 제외)을 인 메모리 NSString
로 가져 와서 작업 할 수 있도록하고 싶습니다. 전화를 걸지 않고 -[NSData description]
lt / gt 따옴표를 잘라 내고 싶습니다. 나는 이것이 NSData
의 공개 인터페이스의 보장 된 측면이 아니며 향후 변경 될 수 있다고 가정합니다 .)
NSData
객체 의이 표현을 객체로 가져 오는 가장 간단한 방법은 무엇입니까 NSString
(를 호출하는 것 -description
제외)?
모든 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)
}
}
}
나는 디버깅을 위해 예약되는 호출 하지 않는 솔루션에 동의 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];
Data
지금은 컬렉션 이기 때문에 @PassKits의 메서드를 Swift 3을 사용하여 매우 우아하게 작성할 수 있다는 점을 추가하고 싶었습니다 .
extension Data {
var hex: String {
var hexString = ""
for byte in self {
hexString += String(format: "%02X", byte)
}
return hexString
}
}
아니면 ...
extension Data {
var hex: String {
return self.map { b in String(format: "%02X", b) }.joined()
}
}
또는 ...
extension Data {
var hex: String {
return self.reduce("") { string, byte in
string + String(format: "%02X", byte)
}
}
}
@Erik_Aigner의 답변이 가장 마음에 들었습니다. 방금 리팩토링했습니다.
NSData *data = [NSMutableData dataWithBytes:"acani" length:5];
NSUInteger dataLength = [data length];
NSMutableString *string = [NSMutableString stringWithCapacity:dataLength*2];
const unsigned char *dataBytes = [data bytes];
for (NSInteger idx = 0; idx < dataLength; ++idx) {
[string appendFormat:@"%02x", dataBytes[idx]];
}
Swift에서 확장을 만들 수 있습니다.
extension NSData {
func toHexString() -> String {
var hexString: String = ""
let dataBytes = UnsafePointer<CUnsignedChar>(self.bytes)
for (var i: Int=0; i<self.length; ++i) {
hexString += String(format: "%02X", dataBytes[i])
}
return hexString
}
}
그런 다음 간단히 사용할 수 있습니다.
let keyData: NSData = NSData(bytes: [0x00, 0xFF], length: 2)
let hexString = keyData.toHexString()
println("\(hexString)") // Outputs 00FF
Sadly there's no built-in way to produce hex from an NSData, but it's pretty easy to do yourself. The simple way is to just pass successive bytes into sprintf("%02x") and accumulate those into an NSMutableString. A faster way would be to build a lookup table that maps 4 bits into a hex character, and then pass successive nybbles into that table.
While it may not be the most efficient way to do it, if you're doing this for debugging, SSCrypto has a category on NSData which contains two methods to do this (one for creating an NSString of the raw byte values, and one which shows a prettier representation of it).
http://www.septicus.com/SSCrypto/trunk/SSCrypto.m
Seeing there is a Swift 1.2 snippet in the comments, here's the Swift 2 version since C style for loops are deprecated now. Gist with MIT license and two simple unit tests if you care.
Here's the code for your convenience:
import Foundation
extension NSData {
var hexString: String {
let pointer = UnsafePointer<UInt8>(bytes)
let array = getByteArray(pointer)
return array.reduce("") { (result, byte) -> String in
result.stringByAppendingString(String(format: "%02x", byte))
}
}
private func getByteArray(pointer: UnsafePointer<UInt8>) -> [UInt8] {
let buffer = UnsafeBufferPointer<UInt8>(start: pointer, count: length)
return [UInt8](buffer)
}
}
ReferenceURL : https://stackoverflow.com/questions/7520615/how-to-convert-an-nsdata-into-an-nsstring-hex-string
'programing' 카테고리의 다른 글
데이터 소스의 SQL 언어를 구성해야하는 이유는 무엇입니까? (0) | 2021.01.16 |
---|---|
SharePoint 인터뷰 질문 (0) | 2021.01.16 |
사람이 읽을 수있는 파일 형식을 사용해야하는 이유는 무엇입니까? (0) | 2021.01.16 |
PowerShell에 상대 파일 포함 (0) | 2021.01.16 |
MVC 3이 서버에 설치되었으므로 / Account / Login? ReturnUrl = % 2f로 리디렉션 요청 (0) | 2021.01.16 |