Ini adalah kategori yang diterapkan pada NSData yang saya tulis. Ini mengembalikan NSString heksadesimal yang mewakili NSData, di mana datanya bisa berapa pun panjangnya. Mengembalikan string kosong jika NSData kosong.
NSData + Konversi. H
#import <Foundation/Foundation.h>
@interface NSData (NSData_Conversion)
#pragma mark - String Conversion
- (NSString *)hexadecimalString;
@end
NSData + Konversi. 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
Pemakaian:
NSData *someData = ...;
NSString *someDataHexadecimalString = [someData hexadecimalString];
Ini "mungkin" lebih baik daripada menelepon [someData description]
dan kemudian menghilangkan spasi, <, dan>. Menelanjangi karakter terasa terlalu "hacky". Ditambah Anda tidak pernah tahu apakah Apple akan mengubah format NSData -description
di masa depan.
CATATAN: Saya telah meminta orang-orang menghubungi saya tentang pemberian lisensi untuk kode dalam jawaban ini. Dengan ini saya mempersembahkan hak cipta saya dalam kode yang saya posting dalam jawaban ini ke domain publik.
"%02lx"
dengan cast itu, atau cast ke(unsigned int)
, atau lepaskan cast dan gunakan@"%02hhx"
:)[hexString appendFormat:@"%02x", (unsigned int)dataBuffer[i]];
jauh lebih baik (jejak memori lebih kecil)Berikut adalah metode kategori NSData yang sangat dioptimalkan untuk menghasilkan string hex. Meskipun jawaban @Dave Gallagher cukup untuk ukuran yang relatif kecil, kinerja memori dan cpu memburuk untuk data dalam jumlah besar. Saya membuat profil ini dengan file 2MB di iPhone 5. Perbandingan waktu adalah 0,05 vs 12 detik. Jejak memori dapat diabaikan dengan metode ini sementara metode lain meningkatkan tumpukan menjadi 70MB!
sumber
Menggunakan properti deskripsi NSData tidak boleh dianggap sebagai mekanisme yang dapat diterima untuk HEX yang mengkodekan string. Properti itu hanya untuk deskripsi dan dapat berubah kapan saja. Sebagai catatan, sebelum iOS, properti deskripsi NSData bahkan tidak mengembalikan datanya dalam bentuk hex.
Maaf telah mengacaukan solusinya tetapi penting untuk mengambil energi untuk membuat serialnya tanpa membonceng API yang dimaksudkan untuk sesuatu yang lain selain serialisasi data.
sumber
description
mengembalikan string yang dikodekan hex, jadi itu tampaknya masuk akal bagi saya.Berikut adalah cara yang lebih cepat untuk melakukan konversi:
BenchMark (waktu rata-rata untuk konversi data 1024 byte yang diulangi 100 kali):
Dave Gallagher: ~ 8.070 ms
NP Programmer: ~ 0.077 ms
Peter: ~ 0.031 ms Yang
Ini: ~ 0.017 ms
sumber
_hexString
metode): github.com/ZipArchive/ZipArchive/blob/master/SSZipArchive/…Versi Swift fungsional
Satu liner:
Berikut adalah formulir ekstensi yang dapat digunakan kembali dan mendokumentasikan sendiri:
Atau, gunakan
reduce("", combine: +)
alih-alihjoinWithSeparator("")
dilihat sebagai master fungsional oleh rekan-rekan Anda.Sunting: Saya mengubah String ($ 0, radix: 16) menjadi String (format: "% 02x", $ 0), karena satu digit angka diperlukan untuk padding nol
sumber
Jawaban Peter ditransfer ke Swift
swift3
Cepat 5
sumber
Saya perlu memecahkan masalah ini dan menemukan jawabannya di sini sangat berguna, tetapi saya khawatir tentang kinerja. Sebagian besar jawaban ini melibatkan penyalinan data secara massal dari NSData, jadi saya menulis yang berikut ini untuk melakukan konversi dengan overhead rendah:
Ini mengalokasikan ruang dalam string untuk seluruh hasil dan menghindari menyalin konten NSData dengan menggunakan enumerateByteRangesUsingBlock. Mengubah X menjadi x dalam format string akan menggunakan digit hex huruf kecil. Jika Anda tidak menginginkan pemisah antara byte, Anda dapat mengurangi pernyataan tersebut
turun menjadi adil
sumber
NSRange
menunjukkan kisaran dalamNSData
representasi yang lebih besar , bukan dalam buffer byte yang lebih kecil (parameter pertama dari blok yang dipasok keenumerateByteRangesUsingBlock
) yang mewakili satu bagian bersebelahan yang lebih besarNSData
. Jadi,byteRange.length
mencerminkan ukuran buffer byte, tetapibyteRange.location
lokasi dalam yang lebih besarNSData
. Jadi, Anda ingin menggunakanoffset
, bukanbyteRange.location + offset
, untuk mengambil byte.appendFormat
Anda mungkin juga harus mengubahself.length * 3
keself.length * 2
Saya membutuhkan jawaban yang akan berfungsi untuk string panjang variabel, jadi inilah yang saya lakukan:
Berfungsi bagus sebagai ekstensi untuk kelas NSString.
sumber
Anda selalu dapat menggunakan [yourString uppercaseString] untuk membuat huruf kapital dalam deskripsi data
sumber
Cara yang lebih baik untuk membuat serial / deserialisasi NSData ke NSString adalah dengan menggunakan encoder / decoder Google Toolbox untuk Mac Base64. Cukup seret ke Proyek Aplikasi Anda file GTMBase64.m, GTMBase64.he GTMDefines.h dari paket Foundation dan lakukan sesuatu seperti
sumber
string = [data base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]
Berikut adalah solusi menggunakan Swift 3
sumber
sumber
Ubah
%08x
untuk%08X
mendapatkan karakter kapital.sumber
Swift + Properti.
Saya lebih suka memiliki representasi hex sebagai properti (sama dengan
bytes
dandescription
properti):Ide dipinjam dari jawaban ini
sumber
Anda harus menghapus spasi.
Secara pribadi saya
base64
menyandikannyadeviceToken
, tapi ini masalah selera.sumber