簡體   English   中英

將char *轉換為unsigned char *

[英]Converting char* to unsigned char*

如何在C中正確地將char *復制到unsigned char *。以下是我的代碼

int main(int argc, char **argv)
{
    unsigned char *digest;

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

我想正確地將char *數組復制到unsigned char *數組。 我使用上面的代碼得到以下警告

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

編輯 :添加更多信息,我的要求是調用者在主函數中提供SHA摘要作為命令行上的字符串,主函數在內部將其保存在摘要中。 SHA摘要可以使用unsigned char最好地表示。

現在的問題是我無法更改main函數(** char)的簽名,因為main函數解析了它需要的其他參數作為char *而不是unsigned char *。

要避免編譯器警告,您只需要:

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

但是避免編譯器警告往往不是一個好主意; 它告訴你,存在根本的不兼容性。 在這種情況下,不兼容性是char的范圍是-128到+127(通常),而unsigned char是0到+255。

您無法正確復制它,因為類型有所不同,編譯器會警告您。

如果你需要復制argv[2]數組的原始位,你應該使用memcpy函數。

strncpy()調用中拋出簽名

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

或引入另一個變量

#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;
}

另請注意, malloc(20 * sizeof(unsigned char*))可能不是您想要的。 我想你想要malloc(20 * sizeof(unsigned char)) ,或者,如定義sizeof (unsigned char)1malloc(20) 如果你真的想要使用調用中每個元素的大小,請使用對象本身,就像我上面的代碼一樣。

您可以使用memcpy:

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

因為src和dest指針指向的基礎對象類型與此函數無關。

沒有一種方法可以將char *轉換為unsigned char * 它們指向數據,您必須知道數據的格式。

SHA-1哈希至少有3種不同的格式:

  • 原始二進制摘要作為正好20個八位字節的數組
  • 摘要為十六進制字符串,如"e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4"
  • 摘要為Base64字符串,如"5en6G6MezRroT3XKqkdPOmY/BfQ="

您的malloc(20 * sizeof(unsigned char))具有二進制摘要的確切大小,但是太小而不適合十六進制字符串或Base64字符串。 我想unsigned char *指向二進制摘要。

char *來自main()的命令行參數,因此char *可能指向一個字符串。 命令行參數始終是C字符串; 它們以NUL終止符'\\0'結尾,並且從不在字符串中包含'\\0' 原始二進制摘要可能包含'\\0' ,因此它們不能用作命令行參數。

將SHA-1摘要從十六進制字符串轉換為原始二進制文件的代碼可能如下所示

#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;
}

不要使用strncpy(dst, src, 20)來復制原始二進制摘要。 strncpy(3)函數如果找到'\\0'則停止復制; 因此,如果您的摘要包含'\\0' ,則會丟失部分摘要。

只需將(char*)放在它前面或(unsigned char*)

警告就是它所說的,你將一個unsigned char *摘要傳遞給strncpy函數,該函數與它預期的符號不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM