Hex à char array en C

Étant donné une chaîne de valeurs hexadécimales, par exemple “0011223344”, c’est donc 0x00, 0x11, etc.

Comment append ces valeurs à un tableau de caractères?

Équivalent à dire:

char array[4] = { 0x00, 0x11 ... }; 

Vous ne pouvez pas insérer 5 octets de données dans un tableau de 4 octets; cela conduit à des débordements de mémoire tampon.

Si vous avez les chiffres hexadécimaux dans une chaîne, vous pouvez utiliser sscanf() et une boucle:

 #include  #include  int main() { const char *src = "0011223344"; char buffer[5]; char *dst = buffer; char *end = buffer + sizeof(buffer); unsigned int u; while (dst < end && sscanf(src, "%2x", &u) == 1) { *dst++ = u; src += 2; } for (dst = buffer; dst < end; dst++) printf("%d: %c (%d, 0x%02x)\n", dst - buffer, (isprint(*dst) ? *dst : '.'), *dst, *dst); return(0); } 

Notez que l’impression de la chaîne commençant par un zéro octet nécessite des précautions; la plupart des opérations se terminent au premier octet nul. Notez que ce code n'a pas terminé le tampon de manière nulle; il n'est pas clair si la terminaison nulle est souhaitable, et il n'y a pas assez d'espace dans le tampon que j'ai déclaré pour append un terminal nul (mais cela est facilement corrigé). Il y a de bonnes chances que, si le code était empaqueté en tant que sous-programme, il devrait renvoyer la longueur de la chaîne convertie (bien que vous puissiez également affirmer que c'est la longueur de la chaîne source divisée par deux).

Je ferais quelque chose comme ça;

 // Convert from ascii hex representation to binary // Examples; // "00" -> 0 // "2a" -> 42 // "ff" -> 255 // Case insensitive, 2 characters of input required, no error checking int hex2bin( const char *s ) { int ret=0; int i; for( i=0; i<2; i++ ) { char c = *s++; int n=0; if( '0'<=c && c<='9' ) n = c-'0'; else if( 'a'<=c && c<='f' ) n = 10 + c-'a'; else if( 'A'<=c && c<='F' ) n = 10 + c-'A'; ret = n + ret*16; } return ret; } int main() { const char *in = "0011223344"; char out[5]; int i; // Hex to binary conversion loop. For example; // If in="0011223344" set out[] to {0x00,0x11,0x22,0x33,0x44} for( i=0; i<5; i++ ) { out[i] = hex2bin( in ); in += 2; } return 0; } 

Si la chaîne est correcte et qu’il n’est pas nécessaire de conserver son contenu, je le ferais de cette façon:

 #define hex(c) ((*(c)>='a')?*(c)-'a'+10:(*(c)>='A')?*(c)-'A'+10:*(c)-'0') void hex2char( char *to ){ for(char *from=to; *from; from+=2) *to++=hex(from)*16+hex(from+1); *to=0; } 

EDIT 1: désolé, j’oublie de calculer avec les lettres AF (af)

EDIT 2: j’ai essayé d’écrire un code plus pédant:

 #include  int xdigit( char digit ){ int val; if( '0' <= digit && digit <= '9' ) val = digit -'0'; else if( 'a' <= digit && digit <= 'f' ) val = digit -'a'+10; else if( 'A' <= digit && digit <= 'F' ) val = digit -'A'+10; else val = -1; return val; } int xstr2str( char *buf, unsigned bufsize, const char *in ){ if( !in ) return -1; // missing input string unsigned inlen=strlen(in); if( inlen%2 != 0 ) return -2; // hex string must even sized for( unsigned i=0; i 

Essai:

 #include  char buf[100] = "test"; void test( char *buf, const char *s ){ printf("%3i=xstr2str( \"%s\", 100, \"%s\" )\n", xstr2str( buf, 100, s ), buf, s ); } int main(){ test( buf, (char*)0 ); test( buf, "123" ); test( buf, "3x" ); test( (char*)0, "" ); test( buf, "" ); test( buf, "3C3e" ); test( buf, "3c31323e" ); strcpy( buf, "616263" ); test( buf, buf ); } 

Résultat:

  -1=xstr2str( "test", 100, "(null)" ) -2=xstr2str( "test", 100, "123" ) -3=xstr2str( "test", 100, "3x" ) -4=xstr2str( "(null)", 100, "" ) 1=xstr2str( "", 100, "" ) 3=xstr2str( "", 100, "3C3e" ) 5=xstr2str( "", 100, "3c31323e" ) 4=xstr2str( "abc", 100, "abc" ) 

Fatalfloor …

Il y a plusieurs façons de faire cela … premièrement, vous pouvez utiliser memcpy () pour copier la représentation exacte dans le tableau de caractères.

Vous pouvez également utiliser les techniques de décalage et de masquage de bits. J’imagine que c’est ce que vous devez faire, car cela ressemble à un problème de devoirs.

Enfin, vous pouvez utiliser une sorte d’indirection de pointeur de fantaisie pour copier l’emplacement de mémoire dont vous avez besoin.

Toutes ces méthodes sont détaillées ici:

Stocker un int dans un tableau de caractères?

Donner un meilleur moyen:

Chaîne hexadécimale en valeur numérique, c’est-à-dire str [] = “0011223344” en valeur 0x0011223344, utilisez

 value = strtoul(ssortingng, NULL, 16); // or strtoull() 

terminé. Si besoin, supprimez le début de 0x00, voir ci-dessous.

Pour les plates-formes LITTLE_ENDIAN, plus: valeur hexadécimale dans le tableau de caractères, valeur 0x11223344 dans le caractère de char arr [N] = {0x00, 0x11, …}

 unsigned long *hex = (unsigned long*)arr; *hex = htonl(value); // you'd like to remove any beginning 0x00 char *zero = arr; while (0x00 == *zero) { zero++; } if (zero > arr) memmove(zero, arr, sizeof(arr) - (zero - arr)); 

terminé.

Remarques: Pour convertir une chaîne longue en caractères hexadécimaux 64 bits sur un système 32 bits, vous devez utiliser unsigned long long au lieu de unsigned long, et htonl ne suffit pas. Faites-le vous-même comme suit: ou hton64 etc:

 #if __KERNEL__ /* Linux Kernel space */ #if defined(__LITTLE_ENDIAN_BITFIELD) #define hton64(x) __swab64(x) #else #define hton64(x) (x) #endif #elif defined(__GNUC__) /* GNU, user space */ #if __BYTE_ORDER == __LITTLE_ENDIAN #define hton64(x) __bswap_64(x) #else #define hton64(x) (x) #endif #elif ... #endif #define ntoh64(x) hton64(x) 

voir http://effocore.googlecode.com/svn/trunk/devel/effo/codebase/builtin/include/impl/sys/bswap.h

 { char szVal[] = "268484927472"; char szOutput[30]; size_t nLen = strlen(szVal); // Make sure it is even. if ((nLen % 2) == 1) { printf("Error ssortingng must be even number of digits %s", szVal); } // Process each set of characters as a single character. nLen >>= 1; for (size_t idx = 0; idx < nLen; idx++) { char acTmp[3]; sscanf(szVal + (idx << 1), "%2s", acTmp); szOutput[idx] = (char)strtol(acTmp, NULL, 16); } } 

Je cherchais la même chose et, après avoir beaucoup lu, j’ai finalement créé cette fonction. Pensé que cela pourrait aider, quelqu’un

 // in = "63 09 58 81" void hexatoascii(char *in, char* out, int len){ char buf[5000]; int i,j=0; char * data[5000]; printf("\n size %d", strlen(in)); for (i = 0; i < strlen(in); i+=2) { data[j] = (char*)malloc(8); if (in[i] == ' '){ i++; } else if(in[i + 1] == ' '){ i++; } printf("\n %c%c", in[i],in[i+1]); sprintf(data[j], "%c%c", in[i], in[i+1]); j++; } for (i = 0; i < j-1; i++){ int tmp; printf("\n data %s", data[i] ); sscanf(data[i], "%2x", &tmp); out[i] = tmp; } //printf("\n ascii value of hexa %s", out); } 

Disons que ceci est une plate-forme ascii peu-endian. Peut-être que l’OP voulait dire “tableau de caractères” plutôt que “chaîne” .. Nous travaillons avec des paires de masques de caractères et de masques de bits .. remarquez le décalage de x16 ..

 /* not my original work, on stacko somewhere ? */ for (i=0;i < 4;i++) { char a = string[2 * i]; char b = string[2 * i + 1]; array[i] = (((encode(a) * 16) & 0xF0) + (encode(b) & 0x0F)); } 

et la fonction encode () est définie ...

 unsigned char encode(char x) { /* Function to encode a hex character */ /**************************************************************************** * these offsets should all be decimal ..x validated for hex.. * ****************************************************************************/ if (x >= '0' && x <= '9') /* 0-9 is offset by hex 30 */ return (x - 0x30); else if (x >= 'a' && x <= 'f') /* af offset by hex 57 */ return(x - 0x57); else if (x >= 'A' && x <= 'F') /* AF offset by hex 37 */ return(x - 0x37); } 

Cette approche flotte ailleurs, ce n'est pas mon travail d'origine, mais c'est vieux. Pas aimé par les puristes parce que c'est non-portable, mais une extension serait sortingviale.

Tout d’abord, votre question n’est pas très précise. La chaîne est-elle un std::ssortingng ou un tampon de char ? Défini au moment de la compilation?

La mémoire dynamic est presque certainement votre réponse.

 char* arr = (char*)malloc(numberOfValues); 

Ensuite, vous pouvez parcourir l’entrée et l’affecter au tableau.