¿Convertir NSData en cadena?

122

Estoy almacenando una clave privada EVP_PKEY de openssl como nsdata. Para esto, estoy serializando en un flujo de bytes usando el siguiente código

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

donde pkey es de tipo EVP_PKEY. Luego estoy almacenando los bytes del búfer 'p' como NSData usando la línea que se muestra a continuación

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

Ahora lo estoy convirtiendo en un NSString usando el código que se proporciona a continuación, pero cuando lo imprimo en la consola, me da algunos otros caracteres.

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

¿Alguien podría ayudar?

Básicamente, quiero almacenar EVP_PKEY en una base de datos sqlite

estoy en el camino correcto? Gracias.

Zach
fuente
¿Qué quieres decir con "algunos otros personajes"? ¿Está imprimiendo caracteres adicionales al final que no deberían estar allí, o simplemente está imprimiendo caracteres completamente diferentes de lo que espera?
Tom Harrington
Es completamente diferente de lo que será
Zach
¿Está seguro de que los datos están codificados en UTF-8? No estoy familiarizado con i2d_PrivateKey, pero sus resultados sugieren que no está utilizando la codificación de cadena correcta.
Tom Harrington
@TOm: Gracias. fue ASCIIEncoding. Ahora está funcionando bien
Zach
No, no estás en el camino correcto aquí y todas las respuestas parecen incorrectas. Debe usar la codificación base64 si desea convertir los datos en NSDataformato NSString.
Maarten Bodewes

Respuestas:

260

C objetivo

Puede usar (consulte Referencia de clase NSString )

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

Ejemplo:

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

Observación : NSDatatenga en cuenta que el valor debe ser válido para la codificación especificada (UTF-8 en el ejemplo anterior); de lo contrario nil, se devolverá:

Devuelve nil si la inicialización falla por algún motivo (por ejemplo, si los datos no representan datos válidos para la codificación).

Prior Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 en adelante

String(data: yourData, encoding: .utf8)

Consulte String # init (datos: codificación :) Referencia

louiscoquio
fuente
Gracias por tu respuesta, ya lo intenté sin éxito.
Zach
26
En el depurador:po [[NSString alloc] initWithData:myData encoding:4]
Berik
7
¿Cómo puede esta respuesta tener numerosos votos positivos, a pesar de que NSDatapuede contener cualquier valor de byte, incluidos los que están fuera del rango UTF-8?
Maarten Bodewes
2
Porque las personas que están aquí están convirtiendo una respuesta de datos de un servidor a una cadena.
Necro
1
¿Qué pasa si NSData <strong> de hecho </strong> contiene valores fuera del rango UTF-8?
Zennichimaro
24

Swift 3.0 anterior:

String(data: yourData, encoding: NSUTF8StringEncoding)

Para Swift 4.0:

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

Creo que su "P" es el parámetro dataWithBytes

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

debería ser "buf"

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

ya que i2d_PrivateKey pone el puntero al búfer de salida p al final del búfer y espera más entradas, y buf sigue apuntando al principio de su búfer.

El siguiente código funciona para mí, donde pkey es un puntero a 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);

Puede usar un convertidor en línea para convertir sus datos binarios en base 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) y compararlo con la clave privada en su archivo cert después de usar el siguiente comando y comprobando la salida de mypkey.pem:

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

Hice referencia a su pregunta y a este sitio de funciones EVP para obtener mi respuesta.

aspergillusOryzae
fuente
2

Swift 3:

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

Una forma sencilla de convertir NSData arbitrario a NSString es codificarlo en base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Luego, puede almacenarlo en su base de datos para reutilizarlo más tarde. Simplemente decodifíquelo de nuevo a NSData.

Porra
fuente
1

Rápido 5 :

String(data: data!, encoding: String.Encoding.utf8)
Alexander Volkov
fuente
Esta es solo una copia modificada de la respuesta de pierre23 que es mejor para mí: ¡generalmente usé esta página para copiar el código y tuve que modificar yourData a datos! eso lleva tiempo. Ahora yo y tú copiamos y pegamos sin modificación.
Alexander Volkov
Esta no es una pregunta relacionada con Swift. Además, la muestra de código en la pregunta es código Objective-C. Y no, por último, el desenvolvimiento forzado de su código puede provocar bloqueos inesperados.
Cristik
@Cristik La pregunta no está etiquetada como Obj-C.
Eiko
@AlexanderVolkov puedes agregar un fragmento de Xcode para eso, sería incluso más rápido que esto;)
Cristik