c char sha1 unsigned strcpy

Conversión de caracteres*a caracteres sin firmar*



char sha1 (7)

¿Cómo copio correctamente un carácter * a un carácter no firmado * en C. A continuación aparece mi código

int main(int argc, char **argv) { unsigned char *digest; digest = malloc(20 * sizeof(unsigned char)); strncpy(digest, argv[2], 20); return 0; }

Me gustaría copiar correctamente la matriz char * a la matriz char * sin firmar. Recibo la siguiente advertencia usando el código de arriba

warning: pointer targets in passing argument 1 of âstrncpyâ differ in signedness

EDITAR : Agregando más información, mi requisito es que la persona que llama proporcione un resumen de SHA a la función principal como una cadena en la línea de comando y la función principal la guarde internamente en el resumen. El resumen de SHA se puede representar mejor utilizando un carácter sin signo.

Ahora el problema es que no puedo cambiar la firma de la función principal (** char) porque la función principal analiza otros argumentos que requiere como char * y no como unsigned char *.


Deshazte de la firma en la llamada strncpy()

strncpy((char*)digest, argv[2], 20);

o introducir otra variable

#include <stdlib.h> #include <string.h> int main(int argc, char **argv) { unsigned char *digest; void *tmp; /* (void*) is compatible with both (char*) and (unsigned char*) */ digest = malloc(20 * sizeof *digest); if (digest) { tmp = digest; if (argc > 2) strncpy(tmp, argv[2], 20); free(digest); } else { fprintf(stderr, "No memory./n"); } return 0; }

También tenga en cuenta que malloc(20 * sizeof(unsigned char*)) probablemente no sea lo que desea. Creo que quieres malloc(20 * sizeof(unsigned char)) , o, como por definición sizeof (unsigned char) es 1 , malloc(20) . Si realmente desea usar el tamaño de cada elemento de la llamada, use el objeto en sí, como en mi código anterior.


La advertencia es simplemente lo que dice, está pasando un compás de caracteres * sin firmar a la función strncpy que tiene una signatura diferente de la que espera.


No hay una sola manera de convertir char * a unsigned char * . Apuntan a los datos, y usted debe saber el formato de los datos.

Hay al menos 3 formatos diferentes para un hash SHA-1:

  • El compendio binario en bruto como una matriz de exactamente 20 octetos
  • el compendio como una cadena hexadecimal, como "e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • el compendio como una cadena Base64, como "5en6G6MezRroT3XKqkdPOmY/BfQ="

Su malloc(20 * sizeof(unsigned char)) tiene el tamaño exacto de un resumen binario, pero es demasiado pequeño para ajustarse a una cadena hexadecimal o una cadena Base64. Supongo que el unsigned char * apunta a un compendio binario.

Pero el char * vino de los argumentos de la línea de comandos de main() , por lo que el char * probablemente apunta a una cadena. Los argumentos de línea de comando son siempre cadenas C; terminan con el terminador NUL ''/0'' y nunca contienen ''/0'' en la cadena. Los resúmenes binarios sin formato pueden contener ''/0'' , por lo que no funcionan como argumentos de línea de comandos.

El código para convertir un compendio SHA-1 de una cadena hexadecimal a un binario sin formato podría verse como

#include <stdio.h> #include <stdlib.h> unsigned char * sha1_from_hex(char *hex) { int i, m, n, octet; unsigned char *digest; digest = malloc(20); if (!digest) return NULL; for (i = 0; i < 20; i++) { sscanf(hex, " %n%2x%n", &m, &octet, &n); if (m != 0 || n != 2) goto fail; digest[i] = octet; hex += 2; } if (*hex) goto fail; return digest; fail: free(digest); return NULL; }

No utilice strncpy(dst, src, 20) para copiar resúmenes binarios en bruto. La función strncpy(3) deja de copiar si encuentra un ''/0'' ; así que si su compendio contiene ''/0'' , pierde parte del compendio.


No puede copiarlo correctamente ya que hay una diferencia en los tipos, el compilador le advierte sobre eso.

Si necesita copiar bits crudos de la matriz argv[2] , debe usar la función memcpy .


Para evitar la advertencia del compilador, simplemente necesita:

strncpy((char *)digest, argv[2], 20);

Pero evitar la advertencia del compilador a menudo no es una buena idea; Te está diciendo que hay una incompatibilidad fundamental. En este caso, la incompatibilidad es que char tiene un rango de -128 a +127 (normalmente), mientras que unsigned char es de 0 a +255.


Puedes usar memcpy como:

memcpy(digest, argv[2], strlen(argv[2]) + 1);

como el tipo subyacente de objetos señalados por src y los punteros dest son irrelevantes para esta función.


Solo ponga (char*) delante de él o (unsigned char*)