Convertir NSData en chaîne?

122

Je stocke une clé privée openssl EVP_PKEY en tant que nsdata. Pour cela, je suis en train de sérialiser dans un flux d'octets en utilisant le code ci-dessous

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

où pkey est de type EVP_PKEY. Ensuite, je stocke les octets du tampon 'p' en tant que NSData en utilisant la ligne ci-dessous

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

Maintenant, je le convertis en NSString en utilisant le code donné ci-dessous, mais lorsque je l'imprime dans la console, cela donne d'autres caractères.

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

Quelqu'un pourrait-il aider?

Fondamentalement, je veux stocker EVP_PKEY dans une base de données sqlite

suis-je sur la bonne voie? Merci.

Zach
la source
Que voulez-vous dire par "quelques autres personnages"? Est-ce l'impression de caractères supplémentaires à la fin qui ne devraient pas être là, ou est-ce simplement l'impression de caractères complètement différents de ce que vous attendez?
Tom Harrington
C'est complètement différent de ce que c'est d'être
Zach
Êtes-vous sûr que les données sont réellement encodées en UTF-8? Je ne suis pas familier avec i2d_PrivateKey mais vos résultats suggèrent que vous n'utilisez pas le bon encodage de chaîne.
Tom Harrington
@TOm: Merci. c'était ASCIIEncoding. Maintenant ça marche bien
Zach
Non, vous n'êtes pas sur la bonne voie ici, et toutes les réponses semblent incorrectes. Vous devez utiliser le codage Base64 si vous voulez convertir les données NSDataà NSString.
Maarten Bodewes

Réponses:

260

Objectif c

Vous pouvez utiliser (voir NSString Class Reference )

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

Exemple:

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

Remarque : veuillez noter que la NSDatavaleur doit être valide pour l'encodage spécifié (UTF-8 dans l'exemple ci-dessus), sinon nilelle sera retournée:

Renvoie nil si l'initialisation échoue pour une raison quelconque (par exemple si les données ne représentent pas des données valides pour le codage).

Avant Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 et versions ultérieures

String(data: yourData, encoding: .utf8)

Voir String # init (data: encoding :) Référence

louiscoquio
la source
Merci pour votre réponse, j'ai déjà essayé sans succès.
Zach
26
Sur le débogueur:po [[NSString alloc] initWithData:myData encoding:4]
Berik
7
Comment cette réponse peut-elle avoir de nombreux votes positifs, même si le NSDatapeut contenir n'importe quelle valeur d'octet, y compris celles en dehors de la plage UTF-8?
Maarten Bodewes
2
Parce que les gens qui sont ici convertissent une réponse de données d'un serveur en chaîne.
Necro
1
Et si NSData <strong> effectivement </strong> contient des valeurs en dehors de la plage UTF-8?
Zennichimaro
24

Avant Swift 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Pour Swift 4.0:

String(data: yourData, encoding: .utf8)
pierre23
la source
3

Je crois que votre "P" est le paramètre dataWithBytes

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

devrait être "buf"

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

puisque i2d_PrivateKey place le pointeur vers le tampon de sortie p à la fin du tampon et attend d'autres entrées, et buf pointe toujours vers le début de votre tampon.

Le code suivant fonctionne pour moi où pkey est un pointeur vers un EVP_PKEY:

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);

Vous pouvez utiliser un convertisseur en ligne pour convertir vos données binaires en base 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) et le comparer à la clé privée de votre fichier cert après avoir utilisé la commande suivante et vérification de la sortie de mypkey.pem:

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

J'ai référencé votre question et ce site de fonction EVP pour ma réponse.

aspergillusOryzae
la source
2

Swift 3:

String(data: data, encoding: .utf8)
Travis M.
la source
1

Un moyen simple de convertir des NSData arbitraires en NSString consiste à l'encoder en base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Vous pouvez ensuite le stocker dans votre base de données pour une réutilisation ultérieure. Décodez-le simplement en NSData.

Gamelle
la source
1

Swift 5 :

String(data: data!, encoding: String.Encoding.utf8)
Alexandre Volkov
la source
Ceci est juste une copie modifiée de la réponse pierre23 qui est meilleure pour moi - j'ai généralement utilisé cette page pour copier le code et j'ai dû modifier vos données en données! cela prend du temps. Maintenant moi et vous copiez et collez sans modification.
Alexander Volkov
Ce n'est pas une question liée à Swift. De plus, l'exemple de code de la question est du code Objective-C. Et pas enfin, le déballage forcé de votre code peut entraîner des plantages inattendus.
Cristik
@Cristik La question n'est pas étiquetée comme Obj-C.
Eiko
@AlexanderVolkov vous pouvez ajouter un extrait Xcode pour cela, ce serait encore plus rapide que cela;)
Cristik