NSData'yı Dizeye Dönüştür?


122

Bir openssl özel Anahtarını EVP_PKEY'i nsdata olarak saklıyorum. Bunun için aşağıdaki kodu kullanarak bir bayt akışına serileştiriyorum

unsigned char *buf, *p;
int len;
len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
p = buf;
i2d_PrivateKey(pkey, &p);

burada pkey, EVP_PKEY tipindedir. Ardından, aşağıda verilen satırı kullanarak bir NSData olarak 'p' tamponundan baytları depoluyorum.

NSData *keydata = [NSData dataWithBytes:P length:len];

Şimdi aşağıda verilen kodu kullanarak bir NSString'e dönüştürüyorum, ancak konsola yazdırdığımda diğer bazı karakterleri veriyor.

NSString *content =[ NSString stringWithCString:[keydata bytes] encoding:NSUTF8StringEncoding];

Biri yardım edebilir mi?

Temel olarak EVP_PKEY'i bir sqlite veritabanında depolamak istiyorum

doğru yolda mıyım? Teşekkürler.


"Diğer bazı karakterler" ne demek? Sonunda olmaması gereken fazladan karakterleri mi yazdırıyor yoksa beklediğinizden tamamen farklı karakterler mi yazdırıyor?
— Tom Harrington

Olduğundan tamamen farklı
— Zach

Verilerin gerçekten UTF-8 kodlu olduğundan emin misiniz? İ2d_PrivateKey'e aşina değilim, ancak sonuçlarınız doğru dize kodlamasını kullanmadığınızı gösteriyor.
— Tom Harrington

@TOm: Teşekkürler. ASCIIEncoding idi. Şimdi iyi çalışıyor
— Zach

Hayır, burada doğru yolda değilsiniz ve tüm cevaplar yanlış görünüyor. Eğer verileri dönüştürmek istiyorsanız kodlayan base64 kullanmalıdır NSDataiçin NSString.
— Maarten Bodewes

Yanıtlar:


260

Objective-C

Kullanabilirsiniz (bkz. NSString Sınıf Başvurusu )

- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding

Misal:

NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

Açıklama : NSDataDeğerin belirtilen kodlama için geçerli olması gerektiğini lütfen unutmayın (yukarıdaki örnekte UTF-8), aksi takdirde nildöndürülecektir:

Başlatma herhangi bir nedenle başarısız olursa sıfır döndürür (örneğin, veriler kodlama için geçerli verileri temsil etmiyorsa).

Swift 3.0'dan önce

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 İleri

String(data: yourData, encoding: .utf8)

Bkz. Dize # init (veri: kodlama :) Başvuru


Cevabınız için teşekkürler.
— Zach

26
Hata ayıklayıcıda:po [[NSString alloc] initWithData:myData encoding:4]
— Berik

7
NSDataUTF-8 aralığı dışındakiler de dahil olmak üzere herhangi bir bayt değeri içerse bile, bu yanıt nasıl çok sayıda olumlu oy alabilir?
— Maarten Bodewes

2
Çünkü buradaki insanlar, bir sunucudan gelen bir veri yanıtını dizeye dönüştürüyor.
— Necro

1
Ya NSData <strong> gerçekten </strong> UTF-8 aralığı dışında değerler içeriyorsa?
— Zennichimaro

24

Önceki Swift 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 4.0 için:

String(data: yourData, encoding: .utf8)

3

DataWithBytes parametresi olarak "P" nin

NSData *keydata = [NSData dataWithBytes:P length:len];

"buf" olmalı

NSData *keydata = [NSData dataWithBytes:buf length:len];

i2d_PrivateKey, göstericiyi tamponun sonundaki çıktı tamponuna p koyduğundan ve daha fazla girdi beklediğinden ve buf hala arabelleğinizin başlangıcını işaret etmektedir.

Aşağıdaki kod benim için çalışıyor, burada pkey bir EVP_PKEY için bir işaretçi:

unsigned char *buf, *pp;
int len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
pp = buf;
i2d_PrivateKey(pkey, &pp);

NSData* pkeyData = [NSData dataWithBytes:(const void *)buf length:len];
DLog(@"Private key in hex (%d): %@", len, pkeyData);

İkili verilerinizi 64 tabanına ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) dönüştürmek için bir çevrimiçi dönüştürücü kullanabilir ve aşağıdaki komutu kullandıktan sonra sertifika dosyanızdaki özel anahtarla karşılaştırabilirsiniz ve mypkey.pem çıktısını kontrol etmek:

openssl pkcs12 -in myCert.p12 -nocerts -nodes -out mypkey.pem

Cevabım için sorunuza ve bu EVP işlevi sitesine başvurdum .



1

Rasgele NSData'yı NSString'e dönüştürmenin basit bir yolu, onu base64 kodlamaktır.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Daha sonra tekrar kullanmak için veritabanınızda saklayabilirsiniz. Sadece NSData'ya geri döndürün.


1

Swift 5 :

String(data: data!, encoding: String.Encoding.utf8)

Bu sadece benim için daha iyi olan pierre23 cevabının değiştirilmiş bir kopyası - genellikle bu sayfayı kodu kopyalamak için kullandım ve Verinizi veriye dönüştürmek zorunda kaldım! bu zaman alır. Şimdi ben ve sen değişiklik yapmadan kopyalayıp yapıştırıyoruz.
— Alexander Volkov

Bu Swift ile ilgili bir soru değil. Dahası, sorudaki kod örneği Objective-C kodudur. Ve son olarak, kodunuzdan zorla açılma beklenmedik çökmelere neden olmaz.
— Cristik

@Cristik Soru Obj-C olarak etiketlenmemiş.
— Eiko

@AlexanderVolkov bunun için bir Xcode pasajı ekleyebilirsiniz, bundan daha da hızlı olacaktır;)
— Cristik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.