Dies ist eine Kategorie, die auf NSData angewendet wird, die ich geschrieben habe. Es wird ein hexadezimaler NSString zurückgegeben, der die NSData darstellt, wobei die Daten eine beliebige Länge haben können. Gibt eine leere Zeichenfolge zurück, wenn NSData leer ist.
NSData + Conversion.h
#import <Foundation/Foundation.h>
@interface NSData (NSData_Conversion)
#pragma mark - String Conversion
- (NSString *)hexadecimalString;
@end
NSData + Conversion.m
#import "NSData+Conversion.h"
@implementation NSData (NSData_Conversion)
#pragma mark - String Conversion
- (NSString *)hexadecimalString {
/* Returns hexadecimal string of NSData. Empty string if data is empty. */
const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
if (!dataBuffer)
return [NSString string];
NSUInteger dataLength = [self length];
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for (int i = 0; i < dataLength; ++i)
[hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
return [NSString stringWithString:hexString];
}
@end
Verwendung:
NSData *someData = ...;
NSString *someDataHexadecimalString = [someData hexadecimalString];
Dies ist "wahrscheinlich" besser als das Aufrufen [someData description]
und anschließende Entfernen der Leerzeichen, <und>. Das Strippen von Charakteren fühlt sich einfach zu "hackig" an. Außerdem wissen Sie nie, ob Apple die Formatierung von NSData -description
in Zukunft ändern wird.
HINWEIS: Ich wurde von Leuten bezüglich der Lizenzierung des Codes in dieser Antwort kontaktiert. Hiermit widme ich mein Urheberrecht an dem Code, den ich in dieser Antwort veröffentlicht habe, der Öffentlichkeit.
"%02lx"
mit dieser Besetzung sein oder in die Besetzung gegossen(unsigned int)
werden oder die Besetzung fallen lassen und verwenden@"%02hhx"
:)[hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
ist viel besser (kleinerer Speicherbedarf)Hier ist eine hochoptimierte NSData-Kategoriemethode zum Generieren einer Hex-Zeichenfolge. Während die Antwort von @Dave Gallagher für eine relativ kleine Größe ausreicht, verschlechtern sich die Speicher- und CPU-Leistung für große Datenmengen. Ich habe dies mit einer 2-MB-Datei auf meinem iPhone 5 profiliert. Der Zeitvergleich betrug 0,05 gegenüber 12 Sekunden. Der Speicherbedarf ist bei dieser Methode vernachlässigbar, während bei der anderen Methode der Heap auf 70 MB vergrößert wurde!
quelle
Die Verwendung der description-Eigenschaft von NSData sollte nicht als akzeptabler Mechanismus für die HEX-Codierung der Zeichenfolge angesehen werden. Diese Eigenschaft dient nur zur Beschreibung und kann jederzeit geändert werden. Vor iOS gab die NSData-Beschreibungseigenschaft ihre Daten nicht einmal in hexadezimaler Form zurück.
Es tut uns leid, dass Sie an der Lösung gearbeitet haben, aber es ist wichtig, dass Sie sich die Energie nehmen, um sie zu serialisieren, ohne eine API zu deaktivieren, die für etwas anderes als die Serialisierung von Daten gedacht ist.
quelle
description
eine hexadezimal codierte Zeichenfolge zurückgegeben wird, was mir vernünftig erscheint.Hier ist ein schnellerer Weg, um die Konvertierung durchzuführen:
BenchMark (mittlere Zeit für eine 100-mal wiederholte Datenkonvertierung von 1024 Byte):
Dave Gallagher: ~ 8,070 ms
NSProgrammer: ~ 0,077 ms
Peter: ~ 0,031 ms
This One: ~ 0,017 ms
quelle
_hexString
Methode): github.com/ZipArchive/ZipArchive/blob/master/SSZipArchive/…Funktionale Swift-Version
Einzeiler:
Hier ist eine wiederverwendbare und selbstdokumentierende Erweiterungsform:
Alternativ können Sie verwenden,
reduce("", combine: +)
anstattjoinWithSeparator("")
von Ihren Kollegen als funktionaler Master angesehen zu werden.Bearbeiten: Ich habe String ($ 0, Radix: 16) in String (Format: "% 02x", $ 0) geändert, da einstellige Zahlen eine Auffüll-Null benötigen
quelle
Peters Antwort wurde auf Swift übertragen
swift3
Swift 5
quelle
Ich musste dieses Problem lösen und fand die Antworten hier sehr nützlich, aber ich mache mir Sorgen um die Leistung. Die meisten dieser Antworten beinhalten das Kopieren der Daten in großen Mengen aus NSData. Daher habe ich Folgendes geschrieben, um die Konvertierung mit geringem Overhead durchzuführen:
Dadurch wird vorab Speicherplatz in der Zeichenfolge für das gesamte Ergebnis zugewiesen, und es wird vermieden, dass der NSData-Inhalt mithilfe von enumerateByteRangesUsingBlock jemals kopiert wird. Wenn Sie das X in ein x in der Formatzeichenfolge ändern, werden Hex-Ziffern in Kleinbuchstaben verwendet. Wenn Sie kein Trennzeichen zwischen den Bytes möchten, können Sie die Anweisung reduzieren
auf nur
quelle
NSRange
Bereich innerhalb der größerenNSData
Darstellung angibt , nicht innerhalb des kleineren Bytepuffers (des ersten Parameters des Blocks, an den geliefert wirdenumerateByteRangesUsingBlock
), der einen einzelnen zusammenhängenden Teil des größeren darstelltNSData
. SomitbyteRange.length
spiegelt sich die Größe des Bytepuffers wider, aber dasbyteRange.location
ist der Ort innerhalb des größerenNSData
. Sie möchten also einfach das Byte abrufenoffset
, nichtbyteRange.location + offset
.appendFormat
, sollten Sie wahrscheinlich auch dieself.length * 3
zuself.length * 2
Ich brauchte eine Antwort, die für Zeichenfolgen mit variabler Länge funktioniert. Deshalb habe ich Folgendes getan:
Funktioniert hervorragend als Erweiterung für die NSString-Klasse.
quelle
Sie können jederzeit [yourString uppercaseString] verwenden, um Buchstaben in der Datenbeschreibung groß zu schreiben
quelle
Eine bessere Möglichkeit, NSData in NSString zu serialisieren / deserialisieren, ist die Verwendung der Google Toolbox für Mac Base64-Encoder / -Decoder. Ziehen Sie einfach die Dateien GTMBase64.m, GTMBase64.he GTMDefines.h aus dem Paket Foundation in Ihr App-Projekt und tun Sie so etwas
quelle
string = [data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]
Hier ist eine Lösung mit Swift 3
quelle
quelle
Wechseln Sie
%08x
zu%08X
, um Großbuchstaben zu erhalten.quelle
Swift + Property.
Ich bevorzuge eine hexadezimale Darstellung als Eigenschaft (die gleichen wie
bytes
unddescription
Eigenschaften):Aus dieser Antwort ist eine Idee entlehnt
quelle
Sie müssen die Leerzeichen entfernen.
Persönlich
base64
verschlüssele ich dasdeviceToken
, aber es ist Geschmackssache.quelle