आप बाइट सरणी को C में हेक्साडेसिमल स्ट्रिंग में कैसे बदलते हैं?


88

मेरे पास है:

uint8 buf[] = {0, 1, 10, 11};

मैं बाइट सरणी को स्ट्रिंग में बदलना चाहता हूं ताकि मैं प्रिंट का उपयोग करके स्ट्रिंग को प्रिंट कर सकूं:

printf("%s\n", str);

और (कॉलन आवश्यक नहीं हैं):

"00:01:0A:0B"

किसी भी तरह की सहायता का स्वागत किया जाएगा।


buf[i]के लिए unsigned charbuf[i] > 127buf_ptr += sprintf(buf_ptr, "%02X", (unsigned char)buf[i]);
डाली

जवाबों:


93
printf("%02X:%02X:%02X:%02X", buf[0], buf[1], buf[2], buf[3]);

अधिक सामान्य तरीके से:

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) printf(":");
    printf("%02X", buf[i]);
}
printf("\n");

एक स्ट्रिंग को समेटने के लिए, कुछ तरीके हैं जिनसे आप यह कर सकते हैं ... मैं शायद एक सूचक को स्ट्रिंग के अंत तक रखूंगा और स्प्रिंट का उपयोग कर सकता हूं। आपको यह सुनिश्चित करने के लिए सरणी के आकार का भी हिसाब रखना चाहिए कि यह आवंटित स्थान से बड़ा नहीं है:

int i;
char* buf2 = stringbuf;
char* endofbuf = stringbuf + sizeof(stringbuf);
for (i = 0; i < x; i++)
{
    /* i use 5 here since we are going to add at most 
       3 chars, need a space for the end '\n' and need
       a null terminator */
    if (buf2 + 5 < endofbuf)
    {
        if (i > 0)
        {
            buf2 += sprintf(buf2, ":");
        }
        buf2 += sprintf(buf2, "%02X", buf[i]);
    }
}
buf2 += sprintf(buf2, "\n");

धन्यवाद मार्क - मेरी समस्या थोड़ी अधिक जटिल है। मेरे पास वास्तव में एक्स बाइट्स की लंबाई के साथ एक बफर है। मैं एक्स बाइट्स के लिए ऐसा करने का एक सामान्य तरीका खोजने और परिणाम के रूप में एक स्ट्रिंग होने की उम्मीद कर रहा था।
स्टीव वॉल्श

किसी भी बाइट की संख्या को संभालने के लिए कोड जोड़ने के लिए अपडेट किया गया है ... मान लें कि x लंबाई है।
मार्क सिनोविक

धन्यवाद फिर से मार्क, लेकिन मुझे इस समस्या के लिए सबसे मुश्किल बात मिल रही थी कि इसे एक स्ट्रिंग में कैसे प्रिंट किया जाए।
स्टीव वॉल्श

5
printf("%02X", (unsigned char)buf[i]);मूल के रूप में इस्तेमाल किया जाना चाहिए अहस्ताक्षरित
आकर्षण के

3
क्यों नहीं printf("%02hhX", buf[i])?
हिंट्रॉन

32

कंप्लीट के लिए, आप किसी भी भारी लाइब्रेरी फंक्शन (कोई स्निपर, नो स्ट्रैकट, यहां तक ​​कि मेमोरैपी भी नहीं) को कॉल किए बिना भी आसानी से कर सकते हैं। यह उपयोगी हो सकता है, यह कहें कि यदि आप कुछ माइक्रोकंट्रोलर या OS कर्नेल की प्रोग्रामिंग कर रहे हैं, जहां libc उपलब्ध नहीं है।

कुछ भी नहीं वास्तव में फैंसी आप के आसपास समान कोड पा सकते हैं यदि आप इसके लिए Google। वास्तव में यह स्निपरफ और बहुत तेज कॉल करने की तुलना में अधिक जटिल नहीं है।

#include <stdio.h>

int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    int i = 0;
    for(; i < sizeof(buf)-1; ++i){
        *pout++ = hex[(*pin>>4)&0xF];
        *pout++ = hex[(*pin++)&0xF];
        *pout++ = ':';
    }
    *pout++ = hex[(*pin>>4)&0xF];
    *pout++ = hex[(*pin)&0xF];
    *pout = 0;

    printf("%s\n", str);
}

यहाँ एक और छोटा संस्करण है। यह केवल इंटरमीडिएट इंडेक्स वेरिएबल i और डुप्लीकेट लास्ट केस कोड (लेकिन टर्मिनेशन कैरेक्टर दो बार लिखा जाता है) से बचता है।

#include <stdio.h>
int main(){
    unsigned char buf[] = {0, 1, 10, 11};
    /* target buffer should be large enough */
    char str[12];

    unsigned char * pin = buf;
    const char * hex = "0123456789ABCDEF";
    char * pout = str;
    for(; pin < buf+sizeof(buf); pout+=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
    }
    pout[-1] = 0;

    printf("%s\n", str);
}

नीचे एक और संस्करण है जो एक टिप्पणी का जवाब देने के लिए कह रहा है कि मैंने इनपुट बफर के आकार को जानने के लिए "ट्रिक" का उपयोग किया है। वास्तव में यह एक ट्रिक नहीं है, बल्कि एक आवश्यक इनपुट ज्ञान है (आपको उस डेटा के आकार को जानना होगा जिसे आप परिवर्तित कर रहे हैं)। मैंने रूपांतरण कोड को एक अलग फ़ंक्शन में निकालकर इसे स्पष्ट किया है। मैंने लक्ष्य बफर के लिए सीमा चेक कोड भी जोड़ा है, जो वास्तव में आवश्यक नहीं है यदि हम जानते हैं कि हम क्या कर रहे हैं।

#include <stdio.h>

void tohex(unsigned char * in, size_t insz, char * out, size_t outsz)
{
    unsigned char * pin = in;
    const char * hex = "0123456789ABCDEF";
    char * pout = out;
    for(; pin < in+insz; pout +=3, pin++){
        pout[0] = hex[(*pin>>4) & 0xF];
        pout[1] = hex[ *pin     & 0xF];
        pout[2] = ':';
        if (pout + 3 - out > outsz){
            /* Better to truncate output string than overflow buffer */
            /* it would be still better to either return a status */
            /* or ensure the target buffer is large enough and it never happen */
            break;
        }
    }
    pout[-1] = 0;
}

int main(){
    enum {insz = 4, outsz = 3*insz};
    unsigned char buf[] = {0, 1, 10, 11};
    char str[outsz];
    tohex(buf, insz, str, outsz);
    printf("%s\n", str);
}

1
यह एक चाल नहीं है, केवल एक स्थिरांक है। प्रश्न के संदर्भ में यह स्पष्ट है कि हम जिस स्रोत को हेक्साडेसिमल में बदलना चाहते हैं वह अच्छी तरह से ज्ञात है (मैं आकार के बजाय कुछ हार्डकोड 4 डाल सकता था)। सामान्य स्थिति में फ़ंक्शन को ज्ञात लंबाई के कुछ इनपुट पर बुलाया जाना चाहिए और लक्ष्य बफर में 3 बार + 1 बाइट्स उपलब्ध हैं। यह कॉलर द्वारा सुनिश्चित किया जाना चाहिए, उस कार्य को करने के लिए रूपांतरण फ़ंक्शन का कोई कारण नहीं है। स्ट्रैलेन को कॉल करना () कुछ मामलों में स्रोत के आकार को खोजने का एक तरीका हो सकता है, लेकिन हमेशा नहीं। क्या होगा यदि संख्या को हेक्स में बदलने के लिए शून्य हो?
kriss

अपने कार्य से प्रेरित होकर, मैं एक संस्करण है जो भी आदि उत्पादन बफर के लिए लिखा बाइट की संख्या, snprintf के समान है, रिटर्न लिखा gist.github.com/cellularmitosis/0d8c0abf7f8aa6a2dff3
जेसन Pepas

मुझे लगता है कि आपको अपने आउटपुट बफ़र को सही आकार में स्वचालित रूप से char str [sizeof (buf) * 3 + 1] का उपयोग करना चाहिए;
सेसिल वार्ड

इसके अलावा और भी बहुत सी चीजें आपको सुरक्षित करेंगी। उदाहरण के लिए "const अहस्ताक्षरित char const * p" ताकि आप यह सुनिश्चित कर सकें कि इनपुट बफ़र्स को नहीं लिखा गया है। एक पते (या 'पॉइंटर') को स्थिर या परिवर्तनशील बनाता है, और दूसरा उस पते पर मेमोरी रीड-ओनली या नहीं बनाता है। अक्सर आपको संकेत मिलाने से रोकता है। और यह भी कि सार्थक नाम होने से इनपुट और आउटपुट के लिए कौन से दस्तावेज़ बफ़र और पॉइंटर्स हैं।
सेसिल वार्ड

@ सीसिल वॉर: जब तक कि मेरा कोड कागज़ का उपयोग करने से बोगस नहीं हो जाता है, तब तक आप बहुत हद तक सुरक्षित नहीं रह पाएंगे, क्योंकि आप पॉइंटर्स को मिक्स करके या इनपुट और आउटपुट के लिए एक ही पॉइंटर का उपयोग करते हैं (ठीक है, अभी भी संभव है)। लेकिन यह कंपाइलर को कोड ऑप्टिमाइज़ करने में भी मदद करेगा। यहां तक ​​कि बेहतर होगा कि प्रतिबंधित कीवर्ड का भी उपयोग करें (बहुत बुरा C99 नहीं C ++, लेकिन अक्सर एक संकलक विस्तार के रूप में मौजूद होता है)। आप इनपुट बफर inऔर आउटपुट बफर को कॉल करने के लिए और अधिक क्या चाहते हैं out? मैं एक स्ट्रिंग का उपयोग करने का विकल्प भी चुन सकता था और आउटपुट बफर प्रदान करने के बजाय एक प्रतिलिपि लौटा सकता था, आधुनिक C ++ ऑप्टिमाइज़र में बहुत परवाह नहीं है।
क्रिश

15

यहाँ एक तरीका है जो तेजी से रास्ता है:

#include <stdlib.h>
#include <stdio.h>

unsigned char *     bin_to_strhex(const unsigned char *bin, unsigned int binsz,
                                  unsigned char **result)
{
  unsigned char     hex_str[]= "0123456789abcdef";
  unsigned int      i;

  if (!(*result = (unsigned char *)malloc(binsz * 2 + 1)))
    return (NULL);

  (*result)[binsz * 2] = 0;

  if (!binsz)
    return (NULL);

  for (i = 0; i < binsz; i++)
    {
      (*result)[i * 2 + 0] = hex_str[(bin[i] >> 4) & 0x0F];
      (*result)[i * 2 + 1] = hex_str[(bin[i]     ) & 0x0F];
    }
  return (*result);
}

int                 main()
{
  //the calling
  unsigned char     buf[] = {0,1,10,11};
  unsigned char *   result;

  printf("result : %s\n", bin_to_strhex((unsigned char *)buf, sizeof(buf), &result));
  free(result);

  return 0
}

3
इस कोड में एक बग होता है जो केवल अजीब गैर-मुद्रण योग्य इनपुट पर ही प्रकट होता है (गणितीय रूप से जो चल रहा है उसे खोदने का समय नहीं है)। हेक्साडेसिमल के बाइनरी को एनकोड करने की कोशिश करें ca9e3c972f1c5db40c0b4a66ab5bc1a20ca4457bdbe5e0f8925896d5ed37d726और आप ÌaÌe3cÌ72f1c5dÌ40c0b4a66Ìb5bÌ1Ì20cÌ4457bÌbÌ5Ì0Ì8Ì258Ì6Ì5Ìd37Ì726बाहर निकल जाएंगे । इसे ठीक करने hex_strके लिए, लूप की पहली पंक्ति के अंदर के बिट (input[i] >> 4) & 0x0Fको @ kriss के उत्तर में बदलना होगा। तब यह ठीक काम करता है।
नीमरियो

बग - मॉलोक () विफलता के लिए जाँच नहीं करता है।
सेसिल वार्ड

अहस्ताक्षरित चार का उपयोग हमेशा हर जगह करना बेहतर होता है क्योंकि कोई भी हस्ताक्षर किए गए चार्ट (एक पागल डीईसी पीडीपी 11 हार्डवेयर सुविधा) के जोखिम को नहीं चाहता है, और इस तरह से आप हस्ताक्षर किए गए तुलनाओं के जोखिम को नहीं चलाते हैं या गलत तरीके से हस्ताक्षर किए गए सही बदलावों को भ्रष्ट करते हैं। इस मामले में, निष्पक्ष होने के लिए, कोड हर जगह रक्षात्मक रूप से & 0x0F करता है जो आपको यहां बचाता है।
सेसिल वार्ड

बिन इनपुट पैरामीटर को * अहस्ताक्षरित चार कॉन्स्टेबल * बिन होना चाहिए, स्मृति को इस रूटीन के प्रयोजनों के लिए केवल पढ़ने के लिए घोषित करने के लिए।
सेसिल वार्ड

1
मैंने सेसिल वार्ड के प्रस्तावों को एकीकृत कर दिया है, प्रतिक्रिया के लिए धन्यवाद
Yannuth

14

इसी तरह के जवाब पहले से ही ऊपर मौजूद हैं, मैंने यह बताने के लिए एक जोड़ा कि कोड की निम्नलिखित लाइन वास्तव में कैसे काम करती है:

ptr += sprintf(ptr, "%02X", buf[i])

यह शांत मुश्किल है और समझने में आसान नहीं है, मैंने नीचे टिप्पणी में स्पष्टीकरण दिया:

uint8 buf[] = {0, 1, 10, 11};

/* Allocate twice the number of bytes in the "buf" array because each byte would
 * be converted to two hex characters, also add an extra space for the terminating
 * null byte.
 * [size] is the size of the buf array */
char output[(size * 2) + 1];

/* pointer to the first item (0 index) of the output array */
char *ptr = &output[0];

int i;

for (i = 0; i < size; i++) {
    /* "sprintf" converts each byte in the "buf" array into a 2 hex string
     * characters appended with a null byte, for example 10 => "0A\0".
     *
     * This string would then be added to the output array starting from the
     * position pointed at by "ptr". For example if "ptr" is pointing at the 0
     * index then "0A\0" would be written as output[0] = '0', output[1] = 'A' and
     * output[2] = '\0'.
     *
     * "sprintf" returns the number of chars in its output excluding the null
     * byte, in our case this would be 2. So we move the "ptr" location two
     * steps ahead so that the next hex string would be written at the new
     * location, overriding the null byte from the previous hex string.
     *
     * We don't need to add a terminating null byte because it's been already 
     * added for us from the last hex string. */  
    ptr += sprintf(ptr, "%02X", buf[i]);
}

printf("%s\n", output);

शानदार तर्क। इस चुनौती के लिए एक सुंदर गैर सी + + स्ट्रिंग जवाब के लिए एक घंटे की तलाश कर रहा था!
मार्क टेरिल

6

मैं केवल निम्नलिखित जोड़ना चाहता था, भले ही यह थोड़ा ऑफ-टॉपिक हो (मानक सी नहीं), लेकिन मैं खुद को अक्सर इसके लिए देख रहा हूं, और पहली खोज हिट के बीच इस सवाल पर ठोकर खा रहा हूं। लिनक्स कर्नेल प्रिंट फ़ंक्शन, में printkएक एकल प्रारूप विनिर्देशक के माध्यम से "सीधे" सरणी / मेमोरी सामग्री को आउटपुट करने के लिए प्रारूप विनिर्देशक भी हैं:

https://www.kernel.org/doc/Documentation/printk-formats.txt

Raw buffer as a hex string:
    %*ph    00 01 02  ...  3f
    %*phC   00:01:02: ... :3f
    %*phD   00-01-02- ... -3f
    %*phN   000102 ... 3f

    For printing a small buffers (up to 64 bytes long) as a hex string with
    certain separator. For the larger buffers consider to use
    print_hex_dump(). 

... हालाँकि, ये प्रारूप विनिर्देशक मानक, उपयोगकर्ता-स्थान के लिए मौजूद नहीं हैं (s)printf


4

समाधान

समारोह btoxमनमाने ढंग से डेटा *bbको हेक्साडेसिमल अंकों के एक असमान स्ट्रिंग *xpमें परिवर्तित करता है n:

void btox(char *xp, const char *bb, int n) 
{
    const char xx[]= "0123456789ABCDEF";
    while (--n >= 0) xp[n] = xx[(bb[n>>1] >> ((1 - (n&1)) << 2)) & 0xF];
}

उदाहरण

#include <stdio.h>

typedef unsigned char uint8;

void main(void) 
{
    uint8 buf[] = {0, 1, 10, 11};
    int n = sizeof buf << 1;
    char hexstr[n + 1];

    btox(hexstr, buf, n);
    hexstr[n] = 0; /* Terminate! */
    printf("%s\n", hexstr);
}

परिणाम: 00010A0B

लाइव: Tio.run


1

यह रूपांतरण करने का एक तरीका है:

#include<stdio.h>
#include<stdlib.h>

#define l_word 15
#define u_word 240

char *hex_str[]={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};

main(int argc,char *argv[]) {


     char *str = malloc(50);
     char *tmp;
     char *tmp2;

     int i=0;


     while( i < (argc-1)) {
          tmp = hex_str[*(argv[i]) & l_word];
          tmp2 = hex_str[*(argv[i]) & u_word];

          if(i == 0) { memcpy(str,tmp2,1); strcat(str,tmp);}
          else { strcat(str,tmp2); strcat(str,tmp);}
          i++;
    }

    printf("\n*********  %s  *************** \n", str);

}

1

थोड़ा संशोधित यनिथ संस्करण। यह सिर्फ मैं इसे एक वापसी मूल्य के रूप में पसंद है

typedef struct {
   size_t len;
   uint8_t *bytes;
} vdata;

char* vdata_get_hex(const vdata data)
{
   char hex_str[]= "0123456789abcdef";

   char* out;
   out = (char *)malloc(data.len * 2 + 1);
   (out)[data.len * 2] = 0;
   
   if (!data.len) return NULL;
   
   for (size_t i = 0; i < data.len; i++) {
      (out)[i * 2 + 0] = hex_str[(data.bytes[i] >> 4) & 0x0F];
      (out)[i * 2 + 1] = hex_str[(data.bytes[i]     ) & 0x0F];
   }
   return out;
}


1

यह फ़ंक्शन उपयुक्त है जहां उपयोगकर्ता / कॉलर चाहता है कि हेक्स स्ट्रिंग को एक एरेसी सरणी / बफर में रखा जाए। एक चरित्र बफर में हेक्स स्ट्रिंग के साथ, उपयोगकर्ता / कॉलर अपने स्वयं के मैक्रो / फ़ंक्शन का उपयोग कर सकते हैं या इसे किसी भी स्थान पर लॉग इन कर सकते हैं जिसे वह चाहता है (जैसे फ़ाइल में)। यह फ़ंक्शन कॉलर को प्रत्येक पंक्ति में डालने के लिए (हेक्स) बाइट्स की संख्या को नियंत्रित करने की अनुमति देता है।

/**
 * @fn 
 * get_hex
 *
 * @brief 
 * Converts a char into bunary string 
 *
 * @param[in]   
 *     buf Value to be converted to hex string
 * @param[in]   
 *     buf_len Length of the buffer
 * @param[in]   
 *     hex_ Pointer to space to put Hex string into
 * @param[in]   
 *     hex_len Length of the hex string space
 * @param[in]   
 *     num_col Number of columns in display hex string
 * @param[out]   
 *     hex_ Contains the hex string
 * @return  void
 */
static inline void
get_hex(char *buf, int buf_len, char* hex_, int hex_len, int num_col)
{
    int i;
#define ONE_BYTE_HEX_STRING_SIZE   3
  unsigned int byte_no = 0;

  if (buf_len <= 0) {
      if (hex_len > 0) {
        hex_[0] = '\0';
      }
      return;
  }

  if(hex_len < ONE_BYTE_HEX_STRING_SIZE + 1)
  {
      return;
  }

  do {
         for (i = 0; ((i < num_col) && (buf_len > 0) && (hex_len > 0)); ++i )
         {
            snprintf(hex_, hex_len, "%02X ", buf[byte_no++] & 0xff);
            hex_ += ONE_BYTE_HEX_STRING_SIZE;
            hex_len -=ONE_BYTE_HEX_STRING_SIZE;
            buf_len--;
         }
         if (buf_len > 1)
         {
             snprintf(hex_, hex_len, "\n");
             hex_ += 1;
         }
  } while ((buf_len) > 0 && (hex_len > 0));

}

उदाहरण: कोड

#define DATA_HEX_STR_LEN 5000
    char      data_hex_str[DATA_HEX_STR_LEN];

    get_hex(pkt, pkt_len, data_hex_str, DATA_HEX_STR_LEN, 16);
    //      ^^^^^^^^^^^^                                  ^^
    //      Input byte array                              Number of (hex) byte
    //      to be converted to hex string                 columns in hex string

    printf("pkt:\n%s",data_hex_str) 

आउटपुट

pkt:
BB 31 32 00 00 00 00 00 FF FF FF FF FF FF DE E5 
A8 E2 8E C1 08 06 00 01 08 00 06 04 00 01 DE E5 
A8 E2 8E C1 67 1E 5A 02 00 00 00 00 00 00 67 1E 
5A 01 

0

सी। में इसके लिए कोई आदिम नहीं है। मैं शायद मॉलॉक (या शायद एलाका) इनपुट पर एक लंबा पर्याप्त बफर और लूप। मैंने इसे सी + + के समान डायनामिक स्ट्रिंग लाइब्रेरी (लेकिन सिंटैक्स नहीं!) के साथ भी ostringstreamदेखा है, जो एक बहुत अधिक सामान्य समाधान है, लेकिन यह केवल एक मामले के लिए अतिरिक्त जटिलता के लायक नहीं हो सकता है।


0

यदि आप एक char *स्ट्रिंग में हेक्स मान संग्रहीत करना चाहते हैं , तो आप उपयोग कर सकते हैं snprintf। आपको सभी मुद्रित पात्रों के लिए जगह आवंटित करने की आवश्यकता है, जिसमें प्रमुख शून्य और कोलन शामिल हैं।

मार्क के जवाब पर विस्तार:

char str_buf* = malloc(3*X + 1);   // X is the number of bytes to be converted

int i;
for (i = 0; i < x; i++)
{
    if (i > 0) snprintf(str_buf, 1, ":");
    snprintf(str_buf, 2, "%02X", num_buf[i]);  // need 2 characters for a single hex value
}
snprintf(str_buf, 2, "\n\0"); // dont forget the NULL byte

तो अब str_bufहेक्स स्ट्रिंग शामिल होंगे।


यह पहले 2 अक्षरों को ओवर राइट करता है .. सही?
xordon

0

जिंक का समाधान बृहदान्त्र में शामिल करने के लिए अनुकूलित:

char buf[] = {0,1,10,11};
int i, size = sizeof(buf) / sizeof(char);
char *buf_str = (char*) malloc(3 * size), *buf_ptr = buf_str;
if (buf_str) {
  for (i = 0; i < size; i++)
    buf_ptr += sprintf(buf_ptr, i < size - 1 ? "%02X:" : "%02X\0", buf[i]);
  printf("%s\n", buf_str);
  free(buf_str);
}

0

मैं C ++ संस्करण को यहां किसी ऐसे व्यक्ति के लिए जोड़ूंगा जो रुचि रखता है।

#include <iostream>
#include <iomanip>
inline void print_bytes(char const * buffer, std::size_t count, std::size_t bytes_per_line, std::ostream & out) {
    std::ios::fmtflags flags(out.flags()); // Save flags before manipulation.
    out << std::hex << std::setfill('0');
    out.setf(std::ios::uppercase);
    for (std::size_t i = 0; i != count; ++i) {
        auto current_byte_number = static_cast<unsigned int>(static_cast<unsigned char>(buffer[i]));
        out << std::setw(2) << current_byte_number;
        bool is_end_of_line = (bytes_per_line != 0) && ((i + 1 == count) || ((i + 1) % bytes_per_line == 0));
        out << (is_end_of_line ? '\n' : ' ');
    }
    out.flush();
    out.flags(flags); // Restore original flags.
}

यह की hexdump प्रिंट होगा bufferलंबाई के countलिए std::ostream out(आप इसे करने के लिए डिफ़ॉल्ट कर सकते हैं std::cout)। हर लाइन में bytes_per_lineबाइट्स होंगे, प्रत्येक बाइट को अपरकेस दो अंक वाले हेक्स का उपयोग करके दर्शाया गया है। बाइट्स के बीच एक जगह होगी। और लाइन के अंत में या बफर के अंत में यह एक नई लाइन प्रिंट करेगा। यदि bytes_per_line0 पर सेट है, तो यह new_line प्रिंट नहीं करेगा। अपने लिए प्रयास करें।


0

सरल उपयोग के लिए मैंने एक फ़ंक्शन बनाया जो इनपुट स्ट्रिंग (बाइनरी डेटा) को एन्कोड करता है:

/* Encodes string to hexadecimal string reprsentation
    Allocates a new memory for supplied lpszOut that needs to be deleted after use
    Fills the supplied lpszOut with hexadecimal representation of the input
    */
void StringToHex(unsigned char *szInput, size_t size_szInput, char **lpszOut)
{
    unsigned char *pin = szInput;
    const char *hex = "0123456789ABCDEF";
    size_t outSize = size_szInput * 2 + 2;
    *lpszOut = new char[outSize];
    char *pout = *lpszOut;
    for (; pin < szInput + size_szInput; pout += 2, pin++)
    {
        pout[0] = hex[(*pin >> 4) & 0xF];
        pout[1] = hex[*pin & 0xF];
    }
    pout[0] = 0;
}

उपयोग:

unsigned char input[] = "This is a very long string that I want to encode";
char *szHexEncoded = NULL;
StringToHex(input, strlen((const char *)input), &szHexEncoded);

printf(szHexEncoded);

// The allocated memory needs to be deleted after usage
delete[] szHexEncoded;

0

Yannuth के जवाब के आधार पर लेकिन सरलीकृत।

यहां, लंबाई को dest[]दो बार होने के लिए निहित किया गया है lenऔर इसका आवंटन कॉलर द्वारा प्रबंधित किया जाता है।

void create_hex_string_implied(const unsigned char *src, size_t len, unsigned char *dest)
{
    static const unsigned char table[] = "0123456789abcdef";

    for (; len > 0; --len)
    {
        unsigned char c = *src++;
        *dest++ = table[c >> 4];
        *dest++ = table[c & 0x0f];
    }
}

0

मुझे पता है कि इस सवाल का जवाब पहले से ही है, लेकिन मुझे लगता है कि मेरा समाधान किसी की मदद कर सकता है।

इसलिए, मेरे मामले में मेरे पास कुंजी का प्रतिनिधित्व करने वाला एक बाइट सरणी था और मुझे एक पंक्ति में इसे प्रिंट करने के लिए हेक्साडेसिमल मानों के चार सरणी में इस बाइट सरणी को बदलने की आवश्यकता थी। मैंने अपना कोड इस तरह एक समारोह में निकाला:

char const * keyToStr(uint8_t const *key)
{
    uint8_t offset = 0;
    static char keyStr[2 * KEY_SIZE + 1];

    for (size_t i = 0; i < KEY_SIZE; i++)
    {
        offset += sprintf(keyStr + offset, "%02X", key[i]);
    }
    sprintf(keyStr + offset, "%c", '\0');

    return keyStr;
}

अब, मैं इस तरह से अपने फ़ंक्शन का उपयोग कर सकता हूं:

Serial.print("Public key: ");
Serial.println(keyToStr(m_publicKey));

Serialऑब्जेक्ट Arduino लाइब्रेरी का हिस्सा है और m_publicKeyनिम्नलिखित घोषणा के साथ मेरी कक्षा का सदस्य है uint8_t m_publicKey[32]


0

आप स्निप्रफ और मॉलोक के साथ हल कर सकते हैं।

char c_buff[50];

u8_number_val[] = { 0xbb, 0xcc, 0xdd, 0x0f, 0xef, 0x0f, 0x0e, 0x0d, 0x0c };

char *s_temp = malloc(u8_size * 2 + 1);

for (uint8_t i = 0; i < u8_size; i++)
{
    snprintf(s_temp  + i * 2, 3, "%02x", u8_number_val[i]);
}

snprintf(c_buff, strlen(s_temp)+1, "%s", s_temp );

printf("%s\n",c_buff);

free(s);

OUT: bbccdd0fef0f0e0d0c


-2

क्या जटिल समाधान!
मैलोक और स्प्रिंट और कास्ट ओह माय। (OZ बोली)
और कहीं भी एक भी रेम नहीं। Gosh

कैसे इस तरह से कुछ के बारे में?

main()
{
    // the value
    int value = 16;

    // create a string array with a '\0' ending ie. 0,0,0
    char hex[]= {0,0,'\0'}; 
    char *hex_p=hex;

    //a working variable
    int TEMP_int=0;

    // get me how many 16s are in this code
    TEMP_int=value/16;

    // load the first character up with 
    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // move that pointer to the next (less significant byte)<BR>
    hex_p++;

    // get me the remainder after I have divied by 16
    TEMP_int=value%16;

    // 48+0 gives you ascii 0, 55+10 gives you ascii A
    if (TEMP_int<10) {*hex_p=48+TEMP_int;}
        else {*hex_p=55+TEMP_int;}

    // print the result
    printf("%i , 0x%s",value,hex);

}

ठीक है, अब आपके पास दो हेक्स अंक हैं। यह विभाजकों को जोड़ने और धर्मान्तरित करने के लिए अन्य बाइट्स की देखभाल करने के लिए बनी हुई है। शायद एक लूप के साथ? इसे एक समारोह बनाएं और आपके पास मेरा (लेकिन क्रिया और पढ़ने में कठिन) के समान कुछ होगा। हो सकता है कि दूसरे पोस्टरों पर नाम बुलाने से पहले आपको कम से कम काम खत्म करना चाहिए?
13

1
और स्रोत कोड में टिप्पणियों के बारे में एक शब्द (आरईएम नहीं, यह टिप्पणियों के लिए बुनियादी कीवर्ड है, इससे बचना चाहिए): अंग्रेजी में यह कहते हुए टिप्पणी कि कोड क्या कर रहा है, बहुत बुरा अभ्यास है! हाँ प्रोग्रामर को यह पता होना चाहिए कि मोडुलो ऑपरेटरों का क्या मतलब है (अवशेषों को दें) और यह संख्या एक दूसरे में दिखाई देने वाली संख्या को गिनती है ... और परिणाम प्रिंट करता है। अरे बाप रे!
क्रिश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.